How to efficiently test a JPA repository? - java

Assume the following class & its repository:
import javax.persistence.*;
import java.io.Serializable;
#Entity
public class Student implements Serializable {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
//getters , setters, Contructors
}
And the Repository is :
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentRepository extends JpaRepository<Student, Long> {}
What I did to test is : Configure the application.properties for H2 database and create the following class :
import com.ndongoel.myDHL.repositories.AdresseRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class LoadDB {
private static final Logger log = LoggerFactory.getLogger(LoadDB.class);
#Bean
CommandLineRunner initDatabase(AdresseRepository adresseRepository) {
return args -> {
Student stu = new Student(null,"Mike","Smith");
log.info("Preloading " + studentRepository.save(stu));
}
}
And just Check the console and The H2 database!

Test with testcontainers config looks as follows:
mport org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.containers.PostgreSQLContainer;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringRunner.class)
#SpringBootTest
#ContextConfiguration(initializers = {InternalErrorTest.Initializer.class})
#AutoConfigureMockMvc
public class InternalErrorTest {
#Autowired
private MockMvc mockMvc;
#BeforeClass
public static void setTest() {
DockerProxy.setTesting(true);
postgreSQLContainer.start();
}
#ClassRule
public static PostgreSQLContainer postgreSQLContainer =
new PostgreSQLContainer("postgres:11.1")
.withDatabaseName("myName")
.withUsername("myUsername")
.withPassword("myPassword");
static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
Properties props = new Properties();
props.setProperty("hibernate.connection.url", testUrl);
}
}
//your tests...
}

Related

Spring boot with Mongo db rest Api

I have created a crud application Using spring boot initializer.
Dependencies:
Lombok
Spring Web
Spring Mongo
This app calls from a database/cluster that I have set up on atlas. but I want it to call the correct collection and just do a simple get all api call in postman
but I get a server 500 error
Service Java file:
package com.fullstack.app.Service;
import com.fullstack.app.exception.EntityNotFoundException;
import com.fullstack.app.Model.*;
import com.fullstack.app.Model.Request.WCCreationRequest;
import com.fullstack.app.Repository.StatusData_WCRepo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
#Service
#RequiredArgsConstructor
public class StatusDataService {
private static StatusData_WCRepo wcRepository;
public StatusData createData (WCCreationRequest request) {
StatusData statusData = new StatusData();
BeanUtils.copyProperties(request, statusData);
return wcRepository.save(statusData);
}
public static List<StatusData> getAllData() {
return wcRepository.findAll();
}
}
request:
package com.fullstack.app.Model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.Getter;
import lombok.Setter;
#Getter
#Setter
#Document(collection = "StatusData_WC")
public class StatusData {
#Id
private String ID_Number;
private String Surname;
private String Full_Names;
private String Address;
private String VR;
private Integer Ward;
private Integer VD_Number;
}
Controller:
package com.fullstack.app.Controller;
import com.fullstack.app.Model.StatusData;
import com.fullstack.app.Model.Request.WCCreationRequest;
import com.fullstack.app.Service.StatusDataService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import lombok.RequiredArgsConstructor;
#RestController
#RequestMapping(value = "/api/statusData")
#RequiredArgsConstructor
public class StatusDataController {
private final StatusDataService sdService;
#GetMapping("/statusdata")
public ResponseEntity getAllData(#RequestParam(required = false) String id) {
if (id == null) {
return ResponseEntity.ok(StatusDataService.getAllData());
}
return ResponseEntity.ok(StatusDataService.getAllData());
}
}
Application properties:
spring.data.mongodb.uri=mongodb+srv://*****:******#cluster0.wlmmf.mongodb.net/myFirstDatabase?retryWrites=true&w=majority

how can i get the object not map address?

I'm try to connect java spring boot with mysql. when i run the code i got the map address like this
This is my first code
This is EmpController1
package com.example.rest.controller;
import com.example.rest.repository.R1pro;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.rest.repository.EmpRepository1;
import java.util.ArrayList;
import java.util.List;
#RestController
#RequestMapping(value = "/emp")
#Slf4j
public class EmpController1 {
#Autowired
private EmpRepository1 empRepository1;
#RequestMapping(value="/ee", method = RequestMethod.GET)
#ResponseBody
public String getCategoryList() {
List<String> sj = new ArrayList<String>();
Gson gson= new Gson();
System.out.println(123);
List<R1pro> emps1 = this.empRepository1.findByLimit();
return emps1.toString();
}
}
This is my EmpRepository1 code
package com.example.rest.repository;
import com.example.rest.Emp;
import com.example.rest.Emp1;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface EmpRepository1 extends JpaRepository<Emp1, Integer> {
#Query(value = "select * from d_RANGE limit 1",nativeQuery = true)
public List<R1pro> findByLimit();
}
This is R1pro code
package com.example.rest.repository;
import java.util.Date;
public interface R1pro {
public String USER_ID();
public String CUST_GP();
}
This is my Emp1 code
package com.example.rest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Date;
import java.sql.Timestamp;
#Entity
#Table(name = "TEMP_TEST_M78_2W")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Emp1 {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private String USER_ID;
private String CUST_GP;
}
This is my Application code
package com.example.rest;
import com.example.rest.repository.EmpRepository;
import com.example.rest.repository.EmpRepository1;
import com.example.rest.repository.R1pro;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import java.util.List;
#SpringBootApplication
#Slf4j
public class Application {
#Autowired
EmpRepository empRepository;
#Autowired
EmpRepository1 empRepository1;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
CommandLineRunner start() {
return args -> {mysql();};
}
private void mysql() {
List<R1pro> emp1 = this.empRepository1.findByLimit();
}
}
When i run the code i got this result
[org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap#27ae5583]
So i change the EmpController1 code
package com.example.rest.controller;
import com.example.rest.repository.R1pro;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.rest.repository.EmpRepository1;
import java.util.ArrayList;
import java.util.List;
#RestController
#RequestMapping(value = "/emp")
#Slf4j
public class EmpController1 {
#Autowired
private EmpRepository1 empRepository1;
#RequestMapping(value="/ee", method = RequestMethod.GET)
#ResponseBody
public String getCategoryList() {
List<String> sj = new ArrayList<String>();
Gson gson= new Gson();
System.out.println(123);
List<R1pro> emps1 = this.empRepository1.findByLimit();
for (int i =0; i<emps1.size();i++)
{
sj.add(emps1.get(i).USER_ID()+" "+ emps1.get(i).CUST_GP());
}
return sj.toString();
}
}
When i run the code i got this Error message
java.lang.IllegalArgumentException: Invoked method public abstract java.lang.String com.example.rest.repository.R1pro.USER_ID() is no accessor method!
Actually this method same as mysql data columns
USER_ID varchar(150)
CUST_GP varchar(1)
This is my sql columns informations
I don't know what is the problem also any solution.. so if someone knows that please teach me
I really admire to solve this issue
thank you!
You need to tweak your interface into something like this -
public interface R1pro {
String getUSER_ID();
String getCUST_GP();
}
The resultset is mapped only to the getter methods similar to the one created in Emp1 class

what is the problem using java spring boot

I try to search all data using java-spring-boot with Mysql but when i run the code i got the this error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'emp0_.get_company_name' in 'field list'
This is my Controller code
package com.example.rest.controller;
import com.example.rest.Emp;
import com.example.rest.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
#RequestMapping("emp")
public class EmpController {
#Autowired
private EmpService empService;
#GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<Emp>> getAllEmps() {
List<Emp> emps = empService.findAll();
return new ResponseEntity<List<Emp>>(emps,HttpStatus.OK);
}
}
This is my EmpRepository code
package com.example.rest.repository;
import com.example.rest.Emp;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface EmpRepository extends JpaRepository<Emp, Integer> {
}
This is my EmpService Code
package com.example.rest.service;
import com.example.rest.Emp;
import java.util.List;
public interface EmpService {
List<Emp> findAll();
}
This is my EmpServiceImpl Code
package com.example.rest.service;
import com.example.rest.Emp;
import com.example.rest.repository.EmpRepository;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
#Service
public class EmpServiceImpl implements EmpService {
#Autowired
private EmpRepository empRepository;
#Override
public List<Emp> findAll() {
List<Emp> emps= new ArrayList<>();
empRepository.findAll().forEach((e -> emps.add(e)));
return emps;
}
}
This is my Application Code
package com.example.rest;
import com.example.rest.repository.EmpRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
#SpringBootApplication
#Configuration
public class Application {
#Autowired
EmpRepository empRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class , args);
}
}
This is my Emp Code
package com.example.rest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name = "company")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Emp implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
private Integer idx;
private String company_id;
private String getCompany_name;
}
So if someone knows that what is the problem please tell me if you don't remind with solution
Thank you!
Use #Service annotation on the EmpServiceImpl class and #Repository annotation on the EmpRepository.
#Service
public class EmpServiceImpl implements EmpService {
#Autowired
private EmpRepository empRepository;
#Override
public List<Emp> findAll() {
List<Emp> emps= new ArrayList<>();
empRepository.findAll().forEach((e -> emps.add(e)));
return emps;
}
}
#Repository
public interface EmpRepository extends JpaRepository<Emp, Integer> {
}
Need to add annotation on below class:
#Service
class EmpServiceImpl implements EmpService {
}

Spring boot does not generate the json and shows me the white page

I've done a simple list with sql server, but it doesn't show me the result, it just shows me the white page.
I have no error in the console. Will the sql server 2017 be? please any help?
connection to sql server 2017
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=DB_PRUEBA_V1;integratedSecurity=true
spring.jpa.show-sql=true
#spring.jpa.hibernate.ddl-auto=update
server.port=8090
package app
package app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ProyectoV2Application {
public static void main(String[] args) {
SpringApplication.run(ProyectoV2Application.class, args);
}
}
package model
package model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "TB_USERS")
public class Users implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "COD_USER")
private int codUser;
#Column(name = "NOM_USER")
private String nomUser;
#Column(name = "EMA_USER")
private String emUser;
public int getCodUser() {
return codUser;
}
public void setCodUser(int codUser) {
this.codUser = codUser;
}
public String getNomUser() {
return nomUser;
}
public void setNomUser(String nomUser) {
this.nomUser = nomUser;
}
public String getEmUser() {
return emUser;
}
public void setEmUser(String emUser) {
this.emUser = emUser;
}
}
package repository
package repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import model.Users;
#Repository
public interface UserDAO extends JpaRepository<Users, Integer>{
}
service
package service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import model.Users;
import repository.UserDAO;
#Service
public class UserService {
#Autowired
private UserDAO dao;
public List<Users> lista(){
return dao.findAll();
}
}
package controller
package controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import model.Users;
import service.UserService;
#RestController
#RequestMapping(value = "/CrudUsers")
public class UserController {
#Autowired
private UserService us;
#ResponseBody
#GetMapping(path = "/lista", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Users> lista(){
return us.lista();
}
}
Whitelabel Error Page
Because you created each class in different package like below,
app --> ProyectoV2Application
model --> Users
repository --> UserDAO
service --> UserService
controller --> UserController
But spring boot scans the classes that are either in root package or in sub package of root package, so move all these classes into sub packages of root package
app --> ProyectoV2Application
app.model --> Users
app.repository --> UserDAO
app.service --> UserService
app.controller --> UserController

How to test Spring's Cacheable on a method?

Recently in my project I was asked to use Spring's #Cacheable annotation for one of the method which returns static referenceData from the database. I followed this blog https://medium.com/#d.lopez.j/configuring-multiple-ttl-caches-in-spring-boot-dinamically-75f4aa6809f3 which guides to have caches created dynamically. I am trying to test this implementation by following this SO answer How to test Spring's declarative caching support on Spring Data repositories? and I am facing issues. I am not able to load the properties from the application-test.properties into my test class.
My CachingConfig Class
package org.vinodh.testing;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.Data;
#Configuration
#ConfigurationProperties(prefix = "caching")
#Data
public class CachingConfig {
private Map<String, CacheSpec> specs;
#Data
public static class CacheSpec {
private int minutesToExpire;
private int maximumSize;
public int getMaximumSize() {
return maximumSize;
}
public void setMaximumSize(int maximumSize) {
this.maximumSize = maximumSize;
}
public int getMinutesToExpire() {
return minutesToExpire;
}
public void setMinutesToExpire(int minutesToExpire) {
this.minutesToExpire = minutesToExpire;
}
}
public Map<String, CacheSpec> getSpecs() {
return specs;
}
#Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
if (specs != null) {
List<CaffeineCache> caches = specs.entrySet().stream()
.map(entry -> buildCache(entry.getKey(), entry.getValue())).collect(Collectors.toList());
cacheManager.setCaches(caches);
}
return cacheManager;
}
private CaffeineCache buildCache(String name, CacheSpec specs) {
Caffeine<Object, Object> caffeineBuilder = Caffeine.newBuilder()
.expireAfterWrite(specs.getMinutesToExpire(), TimeUnit.MINUTES).maximumSize(specs.getMaximumSize());
return new CaffeineCache(name, caffeineBuilder.build());
}
}
My Test Class
package org.vinodh.testing;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
#ConfigurationProperties(prefix = "caching")
#ActiveProfiles("test")
#Profile("test")
public class CachingConfigTest {
#Configuration
#EnableCaching
static class NestedCacheConfiguration {
static class CacheSpec {
#SuppressWarnings("unused")
private int minutesToExpire;
#SuppressWarnings("unused")
private int maximumSize;
}
private Map<String, CacheSpec> specs;
public Map<String, CacheSpec> getSpecs() {
return specs;
}
#Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
System.out.println(getSpecs()); // Is null
return cacheManager;
}
}
#Test
public void test() {
System.out.println("Inside Test");
}
}
application-test.properties
caching.specs.test.minutesToExpire=10
caching.specs.test.maximumSize=10

Categories