0% found this document useful (0 votes)
8 views

2-Spring Data Jan 25

The document provides an overview of Spring Data queries, pagination, and service layer implementations for managing products and employee-parking relationships. It includes examples of one-to-one and one-to-many relationships, along with the necessary entities, repositories, and controllers for handling data. Additionally, it addresses issues related to infinite recursion in JSON serialization and provides configuration details for Spring Boot data management.

Uploaded by

suresh
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

2-Spring Data Jan 25

The document provides an overview of Spring Data queries, pagination, and service layer implementations for managing products and employee-parking relationships. It includes examples of one-to-one and one-to-many relationships, along with the necessary entities, repositories, and controllers for handling data. Additionally, it addresses issues related to infinite recursion in JSON serialization and provides configuration details for Spring Boot data management.

Uploaded by

suresh
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 14

Spring data quaries:

---------------------

@Query("select p from Product p")


List<Product> getListOfAllProducts();

@Query("select p from Product p where p.name=?1")


List<Product> getListOfAllProductsBasedOnName(String name);

@Query("select p from Product p where p.name=:name")


List<Product> getListOfAllProductsBasedOnNameV2(@Param("name") String name);

@Query("select p from Product p where p.name=?1 and p.price=?2")


List<Product> getListOfAllProductsBasedOnNameAndPrice(String name, BigDecimal
price);

@Query("select p from Product p where p.name=?1 or p.price=?2")


List<Product> getListOfAllProductsBasedOnNameOrPrice(String name, BigDecimal
price);

List<Product> findByName(String name);

List<Product> findByNameContaining(String name);


List<Product> findByNameLike(String name);
List<Product> findByNameStartingWith(String name);

List<Product> findByNameEndingWith(String name);

List<Product> findByNameIgnoreCase(String name);

List<Product> findByMfgDateAfter(LocalDate date);


List<Product> findByMfgDateBefore(LocalDate date);
List<Product> findByMfgDateBetween(LocalDate date1, LocalDate date);

Spring data pagination:


----------------------

adding multiple products


-----------------------------

List<Product>products=IntStream.rangeClosed(1, 2000)
.mapToObj(i-> new Product("product "+i, new
Random().nextDouble(5000)))
.toList();

//productRepo.saveAll(products);
service layer:
-------------------
public List<Product> getAllProductSorted(String field);
public Page<Product> getAllProductPage(int offset, int pageSize);
public Page<Product> getAllProductPageSorted(String field,int offset, int
pageSize);

service layer implementation


--------------------------

@Override
public List<Product> getAllProductSorted(String field) {
return productRepo.findAll(Sort.by(Sort.Direction.DESC, field));
}

@Override
public Page<Product> getAllProductPage(int offset, int pageSize) {
return productRepo.findAll(PageRequest.of(offset, pageSize));
}

@Override
public Page<Product> getAllProductPageSorted(String field, int offset, int
pageSize) {
return productRepo.findAll(PageRequest.of(offset,
pageSize).withSort(Sort.by(field)));
}

controller layer:
---------------

@GetMapping(path = "productsorted")
public List<Product> getAllProductSorted(@RequestParam(name="field") String
field) {
return productService.getAllProductSorted(field);
}

//productpage?offset=4&pageSize=20
@GetMapping(path = "productpage")
public Page<Product> getAllProductPage(@RequestParam(name="offset") int
offset,@RequestParam(name="pageSize") int pageSize) {
return productService.getAllProductPage(offset, pageSize);
}

//productpagesorted?offset=4&pageSize=20&field=id
@GetMapping(path = "productpagesorted")
public Page<Product> getAllProductPageSorted(int offset, int pageSize,String
field) {
return productService.getAllProductPageSorted(field, offset, pageSize);
}
Joins:
---------

one to one:
-------------
Employee ------------<>-------- Parking

POJO:
------

public class Employee {


private int eid;
private String name;
private double salary;

private Parking parking;


}

public class Parking {


private int pid;
private String loc;
private Employee employee;
}

Entities:
-----------

@Entity
@Table(name = "emp_table")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int eid;
private String name;
private double salary;

@OneToOne(mappedBy = "employee", cascade = CascadeType.ALL, fetch =


FetchType.LAZY)
private Parking parking;

@Entity
@Table(name = "parking_table")
public class Parking {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)


private int pid;
private String loc;

@JoinColumn(name = "eid_fk")
@OneToOne
private Employee employee;
}

Repository:
------------
@Repository
public interface EmployeeRepo extends JpaRepository<Employee, Integer>{

@Repository
public interface ParkingRepo extends JpaRepository<Parking, Integer>{
}

populate some data:


--------------------
Parking parking1=new Parking("A34");
Parking parking2=new Parking("Mw6");
Parking parking3=new Parking("F40");

Employee emp1=new Employee("ekta", 4000.00, parking1);


Employee emp2=new Employee("keshav", 7000.00, parking2);
Employee emp3=new Employee("gunika", 3400.00, parking3);

parking1.setEmployee(emp1);
parking2.setEmployee(emp2);
parking3.setEmployee(emp3);

empRepo.save(emp1);
empRepo.save(emp2);
empRepo.save(emp3);

parkingRepo.save(parking1);
parkingRepo.save(parking2);
parkingRepo.save(parking3);

one to many:
-------------
Department <>-------- Employee

Pojo:
--------

public class Department {


private int did;
private String dname;

private List<Employee>employees=new ArrayList<>();


}
public class Employee {
private int eid;
private String name;
private double salary;

private Department department;


}

Entities:
--------

@Entity
@Table(name = "dept_table")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int did;

private String dname;

@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch =


FetchType.LAZY)
private List<Employee>employees=new ArrayList<>();
}

@Entity
@Table(name = "empdept_table")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int eid;
private String name;

private double salary;

@JoinColumn(name = "did_fk")
@ManyToOne
private Department department;

Initilizing data:
-----------------

Department d1=new Department("fin");


Department d2=new Department("IT");
Department d3=new Department("sales");

Employee emp1=new Employee("ravi", 6000.00, d1);


Employee emp2=new Employee("ekta", 4000.00, d1);
Employee emp3=new Employee("keshav", 7000.00, d2);
Employee emp4=new Employee("gunika", 3400.00, d2);

Employee emp5=new Employee("raj", 7800.00, d3);

//dept 1 have 1,2 emps


d1.getEmployees().add(emp1);
d1.getEmployees().add(emp2);

d2.getEmployees().add(emp3);
d2.getEmployees().add(emp4);

d3.getEmployees().add(emp5);

deptRepo.save(d1);
deptRepo.save(d2);
deptRepo.save(d3);

empRepo.save(emp1);
empRepo.save(emp2);
empRepo.save(emp3);
empRepo.save(emp4);
empRepo.save(emp5);

Repositories:
-------------

dname ename salary

@Repository
public interface DepartmentRepo extends JpaRepository<Department, Integer>{
@Query("SELECT new com.demo.dto.DeptEmpResponse(d.dname, e.name, e.salary)
FROM Department d INNER JOIN d.employees e")
List<DeptEmpResponse> deptEmployeeInformation();
}

@Query("SELECT new com.demo.dto.DeptEmpResponse(d.dname, e.name, e.salary)


FROM Department d INNER JOIN d.employees e")
List<DeptEmpResponse> deptEmployeeInformation();

@Repository
public interface EmployeeRepo extends JpaRepository<Employee, Integer>{
@Query("SELECT e FROM Employee e WHERE e.eid IN (:eid)")
public List<Employee> findEmployeessByIds(@Param("eid") List<Integer> eid);
}

Requst/response DTO:
----------------------

@JsonIgnoreProperties({"rank","location"})
public class DeptEmpResponse {
private String dname;
private String name;
private double salary;
//@JsonIgnore
private int rank;
//@JsonIgnore
private String location;
}

public class EmployeeRequest {


private List<Integer> ids;
}

{
"ids": [1,5]
}

Exception:
---------
public class ResourceNotFoundException extends RuntimeException{
}

Controllers:
------------

@RestController
public class DeptartmentRestController {

private DepartmentRepo deptRepo;

@Autowired
public DeptartmentRestController(DepartmentRepo deptRepo) {
this.deptRepo = deptRepo;
}

@GetMapping(path = "department", produces = MediaType.APPLICATION_JSON_VALUE)


public List<Department> getAllDepartments(){
List<Department> departments=deptRepo.findAll();
return departments;
}

@GetMapping(path = "department/{did}", produces =


MediaType.APPLICATION_JSON_VALUE)
public Department getAnDepartment(@PathVariable(name="did") int did){
Department
department=deptRepo.findById(did).orElseThrow(ResourceNotFoundException::new);
return department;
}
}
@RestController
public class EmployeeRestController {

@Autowired
private DepartmentRepo deptRepo;

@Autowired
private EmployeeRepo empRepo;

@GetMapping(path = "employee", produces = MediaType.APPLICATION_JSON_VALUE)


public List<Employee> getAllEmp() {
List<Employee>employees=empRepo.findAll();
return employees;
}

@GetMapping(path = "selectedemployee", produces =


MediaType.APPLICATION_JSON_VALUE)
public List<Employee> getSelectedEmp(@RequestBody EmployeeRequest
employeeRequest) {

List<Employee>employees=empRepo.findEmployeessByIds(employeeRequest.getIds());
return employees;
}

@GetMapping(path = "empinfo", produces = MediaType.APPLICATION_JSON_VALUE)


public List<DeptEmpResponse> getAllEmployeesWithDeptName() {
List<DeptEmpResponse> empsWithDeptNames =
deptRepo.deptEmployeeInformation();
return empsWithDeptNames;
}

Problem: recursion :
---------------------
one to one

one to many

many to many

Solving Infinite Recursion using @JsonManagedReference and @JsonBackReference


---------------------------------------------------------------------

@JsonIgnore

@JsonManagedReference:
is used on the OneToMany side
it is the forward part of the mapping/reference and the data
gets serialized normally.

@JsonBackReference :
is used at the @ManyToOne side
@JsonBackReference is is the backward side of the mapping and the
data does not get serialized

Steps:
Add @JsonManagedReference to the getPosts method in the User entity
Add @JsonBackReference to the getUser method of the Post entity
Add @JsonManagedReference to the getUsers method of the Location entity
@JsonBackReference to the getLocation method of the User entity

@JsonIdentifyInfo and @JsonIgnore


-------------------------------------

@JsonIgnore
it is an alternative for the @JsonBackReference.
So we can used @JsonIgnore in place of @JsonBackReference

@JsonIdentityInfo
it can be used in place of the both @JsonManagedReference and
@JsonBackReference.
@JsonIdentityInfo annotation is added to the class and NOT to the
methods.

Also, the @JsonIdentityInfo requires some attributes as shown in the code


below:

@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")

public interface DepartmentRepository extends JpaRepository<Department, Integer> {

@Query("SELECT new new demo.EmpDataResponse(d.name, e.name, e.salary) FROM


Department d INNER JOIN d.employees e")
List<EmpDataResponse> deptEmployeeInformation();

EmpDataResponse{
private String dname;
private String name;
private double salary;
}

dname enam ,salary

public class Department {


//
private String dname;
private List<Employee>employees=new ArrayList<>();
public class Employee {

private int eid;


private String name;
private double salary;

private Department department;

Ref:
-----
https://www.appsdeveloperblog.com/infinite-recursion-in-objects-with-bidirectional-
relationships/

Spring boot join: many to many


---------------------------------
N M
Employee--------- <>------- Project

POJO:
------
public class Employee {
private int eid;
private String name;
private double salary;

private List<Project> projects=new ArrayList<>();


}

public class Project {


private int pid;
private String pname;
private String manager;
private LocalDate startDate;

private List<Employee> employees=new ArrayList<>();


}

Entities:
--------
@Entity
@Table(name = "emp_proj_table")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int eid;
private String name;
private double salary;

@ManyToMany(mappedBy = "employees", cascade = CascadeType.ALL)


private List<Project> projects=new ArrayList<>();
}
@Entity
@Table(name = "project_table")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int pid;
private String pname;
private String manager;
private LocalDate startDate;

@JoinTable(name="emp_project_join", joinColumns = @JoinColumn(name="pid_fk"),


inverseJoinColumns = @JoinColumn(name="eid_fk"))
@ManyToMany(cascade = CascadeType.ALL)
private List<Employee> employees=new ArrayList<>();
}

Data init:
-------
Employee emp1 = new Employee("sunita", 4000.00);
Employee emp2 = new Employee("keshav", 7000.00);
Employee emp3 = new Employee("gunika", 3400.00);

Employee emp4 = new Employee("anil", 3400.00);


Employee emp5 = new Employee("sumit", 7900.00);
Employee emp6 = new Employee("umesh", 5600.00);

Employee emp7 = new Employee("vikas", 4000.00);


Employee emp8 = new Employee("neetu", 7000.00);
Employee emp9 = new Employee("kapil", 3400.00);

Project project1=new Project("shopping cart", "raj", LocalDate.of(2021,


Month.JANUARY, 2));
Project project2=new Project("bank app", "ekta", LocalDate.of(2020,
Month.NOVEMBER, 22));
Project project3=new Project("bookstore", "indu", LocalDate.of(2020,
Month.DECEMBER, 12));

project1.getEmployees().add(emp1);
project1.getEmployees().add(emp2);
project1.getEmployees().add(emp3);

project2.getEmployees().add(emp4);
project2.getEmployees().add(emp5);
project2.getEmployees().add(emp6);

project3.getEmployees().add(emp7);
project3.getEmployees().add(emp8);
project3.getEmployees().add(emp9);
emp1.getProjects().add(project1);
emp2.getProjects().add(project1);
emp3.getProjects().add(project1);

emp4.getProjects().add(project2);
emp5.getProjects().add(project2);
emp6.getProjects().add(project2);

emp7.getProjects().add(project3);
emp8.getProjects().add(project3);
emp9.getProjects().add(project3);

projectRepo.save(project1);
projectRepo.save(project2);
projectRepo.save(project3);

empRepo.save(emp1);
empRepo.save(emp2);
empRepo.save(emp3);

empRepo.save(emp4);
empRepo.save(emp5);
empRepo.save(emp6);

empRepo.save(emp7);
empRepo.save(emp8);
empRepo.save(emp9);

Repo:
-----
@Repository
public interface EmployeeRepo extends JpaRepository<Employee, Integer>{

@Repository
public interface ProjectRepo extends JpaRepository<Project, Integer>{

Spring boot data configuration:


---------------------------------
step 1:
-----------
spring.datasource.url=jdbc:mysql://localhost:3306/cris1?
autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
#spring.jpa.hibernate.ddl-auto=create-drop

spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto= update

step 2:
-------------
@Configuration
@PropertySource("classpath:db.properties")
public class DbConfig {

@Autowired
private Environment environment;

@Bean
public DriverManagerDataSource getDriverManagerDataSource() {
DriverManagerDataSource ds=new DriverManagerDataSource();
ds.setUsername(environment.getProperty("jdbc.username"));
ds.setPassword(environment.getProperty("jdbc.password"));
ds.setDriverClassName(environment.getProperty("jdbc.drivername"));
ds.setUrl(environment.getProperty("jdbc.url"));

return ds;
}

@Configuration
@ComponentScan(basePackages = {"com.productapp"})
@EnableTransactionManagement
@Import(DbConfig.class)
@EnableJpaRepositories(basePackages = "com.productapp.repo",
entityManagerFactoryRef = "emf1", transactionManagerRef = "tx1")
public class AppConfig {

@Bean
public LocalContainerEntityManagerFactoryBean emf1(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factoryBean=new
LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setPackagesToScan(new String[] {"com.productapp.entity"});

factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

factoryBean.setJpaProperties(jpaProperites());
return factoryBean;
}

private Properties jpaProperites() {


Properties properties=new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQL57Dialect");

return properties;
}

@Bean
public JpaTransactionManager tx1(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
}

You might also like