In this Post I am showing you how you can easily create Rest API using Hibernate and Spring Boot with ManyToMany Relationships between two Entities.
you can download source code at the end.
Project Structure
Calling Response from Postman tool
------------------------------------------------------------------------------------------------------
Sample Json to Insert Data in Employee and Projects Table by POST request
localhost:9090/Project
{
"projectName": "CRISA",
"employee" : [
{
"employeeName" : "Chetan Shishodia"
},
{
"employeeName" : "Ajay Kumar"
}
]
}
localhost:9090/Employee
{
"employeeName": "Chetan Shishodia",
"projects" : [
{
"projectName" : "CRISA"
},
{
"projectName" : "FOIS"
}
]
}
------------------------------------------------------------------------------------------------------
EmployeeController.java
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.restapi.entities.Employee;
import com.restapi.services.EmployeeService;
@RestController
public class EmployeeController {
@Autowired
EmployeeService empService;
@GetMapping("/home")
public String home() {
return "Welcome in RestApi with ManyToMany Relation home Page";
}
@GetMapping("/Employee")
public List <Employee> getEmp() {
return this.empService.getEmployees();
}
@GetMapping("/Employee/{eid}")
public Employee getEmpById(@PathVariable("eid") Integer eid) {
return this.empService.getEmployee(eid);
}
@PostMapping("/Employee" )
public Employee addEmp(@RequestBody Employee employee) {
return this.empService.addEmployee(employee);
}
@PutMapping("/Employee")
public Employee updateEmp(@RequestBody Employee employee) {
return this.empService.updateEmployee(employee);
}
@DeleteMapping("/Employee/{eid}")
public Integer deleteEmp(@PathVariable("eid") Integer eid) {
return this.empService.deleteEmployee(eid);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.restapi.entities.Employee;
import com.restapi.services.EmployeeService;
@RestController
public class EmployeeController {
@Autowired
EmployeeService empService;
@GetMapping("/home")
public String home() {
return "Welcome in RestApi with ManyToMany Relation home Page";
}
@GetMapping("/Employee")
public List <Employee> getEmp() {
return this.empService.getEmployees();
}
@GetMapping("/Employee/{eid}")
public Employee getEmpById(@PathVariable("eid") Integer eid) {
return this.empService.getEmployee(eid);
}
@PostMapping("/Employee" )
public Employee addEmp(@RequestBody Employee employee) {
return this.empService.addEmployee(employee);
}
@PutMapping("/Employee")
public Employee updateEmp(@RequestBody Employee employee) {
return this.empService.updateEmployee(employee);
}
@DeleteMapping("/Employee/{eid}")
public Integer deleteEmp(@PathVariable("eid") Integer eid) {
return this.empService.deleteEmployee(eid);
}
}
-----------------------------------------------------------------------------------------------------
ProjectControllers.java
package com.restapi.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.restapi.entities.Projects;
import com.restapi.services.ProjectService;
@RestController
public class ProjectControllers{
@Autowired
ProjectService projectService;
@GetMapping("/Project")
public List <Projects> getProjects() {
return this.projectService.getProjects();
}
@GetMapping("/Project/{pid}")
public Projects getProject(@PathVariable("pid") Integer pid) {
return this.projectService.getProject(pid);
}
@PostMapping("/Project")
public Projects addProjects(@RequestBody Projects project) {
return this.projectService.addProject(project);
}
@PutMapping("/Project")
public Projects updateProject(@RequestBody Projects project) {
return this.projectService.updateProject(project);
}
@DeleteMapping("/Project/{pid}")
public Integer deleteProject(@PathVariable("pid") Integer pid) {
return this.projectService.deleteProjects(pid);
}
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.restapi.entities.Projects;
import com.restapi.services.ProjectService;
@RestController
public class ProjectControllers{
@Autowired
ProjectService projectService;
@GetMapping("/Project")
public List <Projects> getProjects() {
return this.projectService.getProjects();
}
@GetMapping("/Project/{pid}")
public Projects getProject(@PathVariable("pid") Integer pid) {
return this.projectService.getProject(pid);
}
@PostMapping("/Project")
public Projects addProjects(@RequestBody Projects project) {
return this.projectService.addProject(project);
}
@PutMapping("/Project")
public Projects updateProject(@RequestBody Projects project) {
return this.projectService.updateProject(project);
}
@DeleteMapping("/Project/{pid}")
public Integer deleteProject(@PathVariable("pid") Integer pid) {
return this.projectService.deleteProjects(pid);
}
}
-------------------------------------------------------------------------------------------------------
EmployeeDao.java
package com.restapi.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.restapi.entities.Employee;
public interface EmployeeDao extends JpaRepository<Employee, Integer>{
}
import org.springframework.data.jpa.repository.JpaRepository;
import com.restapi.entities.Employee;
public interface EmployeeDao extends JpaRepository<Employee, Integer>{
}
-------------------------------------------------------------------------------------------------------
ProjectDao.java
package com.restapi.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.restapi.entities.Projects;
public interface ProjectDao extends JpaRepository<Projects, Integer>{
}
import org.springframework.data.jpa.repository.JpaRepository;
import com.restapi.entities.Projects;
public interface ProjectDao extends JpaRepository<Projects, Integer>{
}
-------------------------------------------------------------------------------------------------------
Employee.java
package com.restapi.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Entity(name="Employee")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer eid;
private String employeeName;
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinTable(name="EmployeeProjectsJoin",
joinColumns = {@JoinColumn(name="eid")},
inverseJoinColumns={@JoinColumn(name="pid")})
@JsonIgnoreProperties("employee")
private List<Projects> projects;
public Integer getEid() {
return eid;
}
public void setEid(Integer eid) {
this.eid = eid;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public List<Projects> getProjects() {
return projects;
}
public void setProjects(List<Projects> projects) {
this.projects = projects;
}
public Employee(Integer eid, String employeeName, List<Projects> projects) {
super();
this.eid = eid;
this.employeeName = employeeName;
this.projects = projects;
}
public Employee() {
super();
}
}
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Entity(name="Employee")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer eid;
private String employeeName;
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinTable(name="EmployeeProjectsJoin",
joinColumns = {@JoinColumn(name="eid")},
inverseJoinColumns={@JoinColumn(name="pid")})
@JsonIgnoreProperties("employee")
private List<Projects> projects;
public Integer getEid() {
return eid;
}
public void setEid(Integer eid) {
this.eid = eid;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public List<Projects> getProjects() {
return projects;
}
public void setProjects(List<Projects> projects) {
this.projects = projects;
}
public Employee(Integer eid, String employeeName, List<Projects> projects) {
super();
this.eid = eid;
this.employeeName = employeeName;
this.projects = projects;
}
public Employee() {
super();
}
}
--------------------------------------------------------------------------------------------------------
Projects.java
package com.restapi.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Entity(name="Projects")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Projects implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer pid;
private String projectName;
@ManyToMany(mappedBy="projects",fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JsonIgnoreProperties("projects")
private List<Employee> employee;
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public List<Employee> getEmployee() {
return employee;
}
public void setEmployee(List<Employee> employee) {
this.employee = employee;
}
public Projects(Integer pid, String projectName, List<Employee> employee) {
super();
this.pid = pid;
this.projectName = projectName;
this.employee = employee;
}
public Projects() {
super();
}
}
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Entity(name="Projects")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Projects implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer pid;
private String projectName;
@ManyToMany(mappedBy="projects",fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JsonIgnoreProperties("projects")
private List<Employee> employee;
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public List<Employee> getEmployee() {
return employee;
}
public void setEmployee(List<Employee> employee) {
this.employee = employee;
}
public Projects(Integer pid, String projectName, List<Employee> employee) {
super();
this.pid = pid;
this.projectName = projectName;
this.employee = employee;
}
public Projects() {
super();
}
}
-------------------------------------------------------------------------------------------------------
EmployeeImpl.java
package com.restapi.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.restapi.dao.EmployeeDao;
import com.restapi.entities.Employee;
@Service
public class EmployeeImpl implements EmployeeService{
@Autowired
EmployeeDao empDao;
@Override
public List<Employee> getEmployees() {
// TODO Auto-generated method stub
return empDao.findAll();
}
@Override
public Employee getEmployee(Integer empId) {
// TODO Auto-generated method stub
return empDao.getOne(empId);
}
@Override
public Employee addEmployee(Employee employee) {
empDao.save(employee);
return employee;
}
@Override
public Employee updateEmployee(Employee employee) {
empDao.save(employee);
return employee;
}
@Override
public Integer deleteEmployee(Integer empId) {
int status =0;
try {
Employee emp = empDao.getOne(empId);
empDao.delete(emp);
status=1;
}catch(Exception ex) {
status=0;
ex.printStackTrace();
return status;
}
return status;
}
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.restapi.dao.EmployeeDao;
import com.restapi.entities.Employee;
@Service
public class EmployeeImpl implements EmployeeService{
@Autowired
EmployeeDao empDao;
@Override
public List<Employee> getEmployees() {
// TODO Auto-generated method stub
return empDao.findAll();
}
@Override
public Employee getEmployee(Integer empId) {
// TODO Auto-generated method stub
return empDao.getOne(empId);
}
@Override
public Employee addEmployee(Employee employee) {
empDao.save(employee);
return employee;
}
@Override
public Employee updateEmployee(Employee employee) {
empDao.save(employee);
return employee;
}
@Override
public Integer deleteEmployee(Integer empId) {
int status =0;
try {
Employee emp = empDao.getOne(empId);
empDao.delete(emp);
status=1;
}catch(Exception ex) {
status=0;
ex.printStackTrace();
return status;
}
return status;
}
}
--------------------------------------------------------------------------------------------------------
EmployeeService.java
package com.restapi.services;
import java.util.List;
import com.restapi.entities.Employee;
public interface EmployeeService {
public List<Employee> getEmployees();
public Employee getEmployee(Integer empId);
public Employee addEmployee(Employee emp);
public Employee updateEmployee(Employee emp);
public Integer deleteEmployee(Integer empId);
}
import java.util.List;
import com.restapi.entities.Employee;
public interface EmployeeService {
public List<Employee> getEmployees();
public Employee getEmployee(Integer empId);
public Employee addEmployee(Employee emp);
public Employee updateEmployee(Employee emp);
public Integer deleteEmployee(Integer empId);
}
-------------------------------------------------------------------------------------------------------
ProjectImpl.java
package com.restapi.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.restapi.dao.ProjectDao;
import com.restapi.entities.Projects;
@Service
public class ProjectImpl implements ProjectService {
@Autowired
ProjectDao projectDao;
@Override
public List<Projects> getProjects() {
// TODO Auto-generated method stub
return projectDao.findAll();
}
@Override
public Projects getProject(Integer projectId) {
// TODO Auto-generated method stub
return projectDao.getOne(projectId);
}
@Override
public Projects addProject(Projects project) {
// TODO Auto-generated method stub
projectDao.save(project);
return project;
}
@Override
public Projects updateProject(Projects project) {
// TODO Auto-generated method stub
projectDao.save(project);
return project;
}
@Override
public Integer deleteProjects(Integer projectId) {
int status =0;
try {
Projects project = projectDao.getOne(projectId);
projectDao.delete(project);
status=1;
}catch(Exception ex) {
status=0;
ex.printStackTrace();
return status;
}
return status;
}
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.restapi.dao.ProjectDao;
import com.restapi.entities.Projects;
@Service
public class ProjectImpl implements ProjectService {
@Autowired
ProjectDao projectDao;
@Override
public List<Projects> getProjects() {
// TODO Auto-generated method stub
return projectDao.findAll();
}
@Override
public Projects getProject(Integer projectId) {
// TODO Auto-generated method stub
return projectDao.getOne(projectId);
}
@Override
public Projects addProject(Projects project) {
// TODO Auto-generated method stub
projectDao.save(project);
return project;
}
@Override
public Projects updateProject(Projects project) {
// TODO Auto-generated method stub
projectDao.save(project);
return project;
}
@Override
public Integer deleteProjects(Integer projectId) {
int status =0;
try {
Projects project = projectDao.getOne(projectId);
projectDao.delete(project);
status=1;
}catch(Exception ex) {
status=0;
ex.printStackTrace();
return status;
}
return status;
}
}
--------------------------------------------------------------------------------------------------------
ProjectService.java
package com.restapi.services;
import java.util.List;
import com.restapi.entities.Projects;
public interface ProjectService {
public List<Projects> getProjects();
public Projects getProject(Integer projectId);
public Projects addProject(Projects project);
public Projects updateProject(Projects project);
public Integer deleteProjects(Integer projectId);
}
import java.util.List;
import com.restapi.entities.Projects;
public interface ProjectService {
public List<Projects> getProjects();
public Projects getProject(Integer projectId);
public Projects addProject(Projects project);
public Projects updateProject(Projects project);
public Integer deleteProjects(Integer projectId);
}
-------------------------------------------------------------------------------------------------------
application.properties
# Changing the server port
server.port=9090
# Database Configuration : Mysql
spring.datasource.url=jdbc:mysql://localhost/Test
spring.datasource.username=root
spring.datasource.password=admin123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jackson.serialization.fail-on-empty-beans=false
server.port=9090
# Database Configuration : Mysql
spring.datasource.url=jdbc:mysql://localhost/Test
spring.datasource.username=root
spring.datasource.password=admin123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jackson.serialization.fail-on-empty-beans=false
-------------------------------------------------------------------------------------------------------
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.restAPI</groupId>
<artifactId>REST</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RestAPI</name>
<description>RestAPI Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.restAPI</groupId>
<artifactId>REST</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RestAPI</name>
<description>RestAPI Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
---------------------------------------------------------------------------------
https://discourse.hibernate.org/t/found-shared-references-to-a-collection/4431
ReplyDeletehttps://hibernate.atlassian.net/browse/HHH-11605