Join tables in spring data jpa - java

I have an issue in joining two tables column. I have two entities Status Report and Employee. and I want the data of employee inside StatusReport.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
#Entity
#Table(name="statusreport")
public class StatusReport {
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private BigInteger EMPID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinTable(name = "Employees")
#JoinColumn(name = "EMPID")
private Employees employee;
public StatusReport(){
}
public StatusReport(BigInteger COMPLIANCEID,BigInteger EMPID,
String COMMENTS,Date CREATEDDATE,BigInteger DEPARTMENT_ID){
this.COMPLIANCEID=COMPLIANCEID;
this.EMPID=EMPID;
this.COMMENTS=COMMENTS;
this.CREATEDDATE=CREATEDDATE;
this.DEPARTMENT_ID=DEPARTMENT_ID;
}
public BigInteger getCOMPLIANCEID() {
return COMPLIANCEID;
}
public void setCOMPLIANCEID(BigInteger COMPLIANCEID) {
this.COMPLIANCEID = COMPLIANCEID;
}
public BigInteger getSTATUSRPTID() {
return STATUSRPTID;
}
public void setSTATUSRPTID(BigInteger STATUSRPTID) {
this.STATUSRPTID = STATUSRPTID;
}
public BigInteger getEMPID() {
return EMPID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public String getCOMMENTS() {
return COMMENTS;
}
public void setCOMMENTS(String COMMENTS) {
this.COMMENTS = COMMENTS;
}
public Date getCREATEDDATE() {
return CREATEDDATE;
}
public void setCREATEDDATE(Date CREATEDDATE) {
this.CREATEDDATE = CREATEDDATE;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public Employees getEmployee() {
return employee;
}
public void setEmployee(Employees employee) {
this.employee = employee;
}
}
Another class is the employee:
package com.sl.ems.models;
import com.sl.ems.utils.Utils;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
#Entity
public class Employees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinTable(name = "Department")
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
public Employees(){
}
public Employees(String FIRSTNAME,String LASTNAME,Date DOB,String EMAIL,BigInteger DEPARTMENT_ID){
this.FIRSTNAME=FIRSTNAME;
this.LASTNAME=LASTNAME;
this.DOB=DOB;
this.EMAIL=EMAIL;
this.DEPARTMENT_ID=DEPARTMENT_ID;
}
public BigInteger getEMPID() {
return EMPID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public String getFIRSTNAME() {
return FIRSTNAME;
}
public void setFIRSTNAME(String FIRSTNAME) {
this.FIRSTNAME = FIRSTNAME;
}
public String getLASTNAME() {
return LASTNAME;
}
public void setLASTNAME(String LASTNAME) {
this.LASTNAME = LASTNAME;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date DOB) {
this.DOB = DOB;
}
public String getEMAIL() {
return EMAIL;
}
public void setEMAIL(String EMAIL) {
this.EMAIL = EMAIL;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
As you can see employee entity itself have some other joins on other tables. Which is a deparment table.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
#Entity
public class Department {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger DEPARTMENT_ID;
private String DEPARTMENT_NM;
public Department(){
}
public Department(String DEPARTMENT_NM){
this.DEPARTMENT_NM=DEPARTMENT_NM;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public String getDEPARTMENT_NM() {
return DEPARTMENT_NM;
}
public void setDEPARTMENT_NM(String DEPARTMENT_NM) {
this.DEPARTMENT_NM = DEPARTMENT_NM;
}
}
When I join Status Report with Employee I get Sql exception. But strangly when I remove join of Department in Employee entity table then I get the result.
Can someone please help if I am missing anything?

Looks like your mapping is not correct. Also verify you have a EMPID column.
You don't need to use the #JoinTable annotation in your case.
StatusReport - removed private BigInteger EMPID; as it is ued n joining
#Entity
#Table(name="statusreport")
public class StatusReport {
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinColumn(name = "EMPID")
private Employees employee;
//others methods
Employee - removed private BigInteger DEPARTMENT_ID; as it is ued n joining
#Entity
public class Employees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;

Well taking help from above post. I made few other changes in my code. As I could not manage to remove the field completely from my entity class so I made it Transient and set its property from the join column object method. So my class are as follows.
Employee class is as follows.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
#Entity
public class Employees {
/**
Author: Puneet Kumar Bahuguna
Year: DEC 2020
Project: SimplyLearn EMS
Description: This Entity class mapped to the employees table in the database.
**/
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
#Transient
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
public Employees(){
}
public Employees(BigInteger EMPID){
this.EMPID=EMPID;
}
public Employees(String FIRSTNAME,String LASTNAME,Date DOB,String EMAIL,Department department){
this.FIRSTNAME=FIRSTNAME;
this.LASTNAME=LASTNAME;
this.DOB=DOB;
this.EMAIL=EMAIL;
this.department=department;
}
public BigInteger getEMPID() {
return EMPID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public String getFIRSTNAME() {
return FIRSTNAME;
}
public void setFIRSTNAME(String FIRSTNAME) {
this.FIRSTNAME = FIRSTNAME;
}
public String getLASTNAME() {
return LASTNAME;
}
public void setLASTNAME(String LASTNAME) {
this.LASTNAME = LASTNAME;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date DOB) {
this.DOB = DOB;
}
public String getEMAIL() {
return EMAIL;
}
public void setEMAIL(String EMAIL) {
this.EMAIL = EMAIL;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
}
StatusReport class is as follows.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
#Entity
#Table(name="statusreport")
public class StatusReport {
/**
Author: Puneet Kumar Bahuguna
Year: DEC 2020
Project: SimplyLearn EMS
Description: This Entity class mapped to the statusreport table in the database.
**/
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#Transient
private BigInteger EMPID;
#OneToOne
#JoinColumn(name = "EMPID")
private Employees employee;
public StatusReport(){
}
public StatusReport(String COMMENTS,Date CREATEDDATE){
}
public StatusReport(BigInteger COMPLIANCEID,String COMMENTS,Date CREATEDDATE,
BigInteger DEPARTMENT_ID,Employees employee){
this.COMPLIANCEID=COMPLIANCEID;
this.COMMENTS=COMMENTS;
this.CREATEDDATE=CREATEDDATE;
this.DEPARTMENT_ID=DEPARTMENT_ID;
this.employee=employee;
}
public BigInteger getCOMPLIANCEID() {
return COMPLIANCEID;
}
public void setCOMPLIANCEID(BigInteger COMPLIANCEID) {
this.COMPLIANCEID = COMPLIANCEID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public BigInteger getEMPID() {
return EMPID;
}
public BigInteger getSTATUSRPTID() {
return STATUSRPTID;
}
public void setSTATUSRPTID(BigInteger STATUSRPTID) {
this.STATUSRPTID = STATUSRPTID;
}
public String getCOMMENTS() {
return COMMENTS;
}
public void setCOMMENTS(String COMMENTS) {
this.COMMENTS = COMMENTS;
}
public Date getCREATEDDATE() {
return CREATEDDATE;
}
public void setCREATEDDATE(Date CREATEDDATE) {
this.CREATEDDATE = CREATEDDATE;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public Employees getEmployee() {
return employee;
}
public void setEmployee(Employees employee) {
this.employee = employee;
}
}
Please also note for example while you are saving a StatusReport object by using save method of jpa you will have to set the EMPID through getEmployee().getEMPID()

Related

ids for this class must be manually assigned before calling save(): com.employeesService.EmployeesService.model.Employee

I have a manyToMany relationship between Department and Employee
Image of Employee schema
My problem came after i changed the composited keys to an Embeddable class and then calling that class as an Id on my DepartmentEmployee class
These are my classes:
DepartmentEmployeeId:
#Embeddable
public class DepartmentEmployeeId implements Serializable {
#Column(name = "dept_no")
private String deptNo;
#Column(name = "emp_no")
private Long empNo;
public DepartmentEmployeeId() {
}
public DepartmentEmployeeId(String deptNo, Long empNo) {
this.deptNo = deptNo;
this.empNo = empNo;
}
public String getDeptNo() {
return deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
public Long getEmpNo() {
return empNo;
}
public void setEmpNo(Long empNo) {
this.empNo = empNo;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
DepartmentEmployeeId that = (DepartmentEmployeeId) o;
return Objects.equals(deptNo, that.deptNo) &&
Objects.equals(empNo, that.empNo);
}
#Override
public int hashCode() {
return Objects.hash(deptNo, empNo);
}
}
Department:
#Entity
#Table(name = "departments")
public class Department {
#Id
#Column(name = "dept_no")
private String deptNo;
#Column(name = "dept_name")
private String deptName;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "department", orphanRemoval = true)
#JsonIgnore
private List<DepartmentEmployee> departmentEmployees = new ArrayList<>();
public String getDeptNo() {
return deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public void addEmployee(DepartmentEmployee departmentEmployee) {
Employee employee=new Employee();
departmentEmployee = new DepartmentEmployee(this, employee);
departmentEmployees.add(departmentEmployee);
}
public List<DepartmentEmployee> getDepartmentEmployees() {
return departmentEmployees;
}
}
Employee:
#Entity
#Table(name = "employees")
public class Employee {
public enum Gender {M, F}
#Id
private Long empNo;
#Column(name = "birth_date")
private LocalDate birthDate;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Enumerated(EnumType.STRING)
#Column(name = "gender")
private Gender gender;
#Column(name = "hire_date")
private LocalDate hireDate;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "emp_no")
#JsonIgnore
private List<Salary> salaries = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "employee",orphanRemoval = true)
#JsonIgnore
private List<DepartmentEmployee> departmentEmployees = new ArrayList<>();
public List<Salary> getSalaries() {
return salaries;
}
public Long getEmpNo() {
return empNo;
}
public void setEmpNo(Long empNo) {
this.empNo = empNo;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public LocalDate getHireDate() {
return hireDate;
}
public void setHireDate(LocalDate hireDate) {
this.hireDate = hireDate;
}
public void assignSalary(Salary salary) {
salaries.add(salary);
}
public List<DepartmentEmployee> getDepartmentEmployees() {
return departmentEmployees;
}
}
Department Employee
#Entity
#Table(name = "dept_emp")
public class DepartmentEmployee {
#EmbeddedId
private DepartmentEmployeeId id;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("deptNo")
private Department department;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("empNo")
private Employee employee;
#Column(name = "from_date")
private LocalDate fromDate;
#Column(name = "to_date")
private LocalDate toDate;
public DepartmentEmployee() {
}
public DepartmentEmployee(Department department, Employee employee) {
this.department=department;
this.employee=employee;
this.id = new DepartmentEmployeeId(department.getDeptNo(), employee.getEmpNo());
}
public DepartmentEmployeeId getId() {
return id;
}
public void setId(DepartmentEmployeeId id) {
this.id = id;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public LocalDate getFromDate() {
return fromDate;
}
public void setFromDate(LocalDate fromDate) {
this.fromDate = fromDate;
}
public LocalDate getToDate() {
return toDate;
}
public void setToDate(LocalDate toDate) {
this.toDate = toDate;
}
}
My Service add method:
#Override
#Transactional
public Employee addEmployeeToDepartment(String deptNo, Long empNo, DepartmentEmployee departmentEmployee) {
Department department = this.departmentRepository.findById(deptNo).orElseThrow(() -> new DepartmentNotFoundException(deptNo));
Employee employee = this.employeeRepository.findById(empNo).orElseThrow(() -> new EmployeeNotFoundException(empNo));
departmentEmployee.setId(new DepartmentEmployeeId(department.getDeptNo(), employee.getEmpNo()));
departmentEmployee.setDepartment(department);
departmentEmployee.setEmployee(employee);
department.addEmployee(departmentEmployee);
this.departmentRepository.save(department);
return employee;
}
I found my problem, it was at this method:
public void addEmployee(DepartmentEmployee departmentEmployee) {
Employee employee=new Employee();
departmentEmployee = new DepartmentEmployee(this, employee);
departmentEmployees.add(departmentEmployee);
}
I was creating a new employee and i was not giving it an id, this is all i had to do:
public void addEmployee(DepartmentEmployee departmentEmployee) {
departmentEmployees.add(departmentEmployee);
}
Its very simple ...
In the Employee class you have
#Entity
#Table(name = "employees")
public class Employee {
public enum Gender {M, F}
#Id
//Add #GenerateValue here
private Long empNo;
You are missing a #GeneratedValue annotation just below the #Id.
For more details see here.

how map join query columns to a class using hibernate?

I tried to create a query that returns different columns from two tables, and I want the query columns to be mapped to the user definition class.
my Student Model :
package com.example.demo.models;
import javax.persistence.*;
import java.util.List;
#Entity
#Table
public class Students {
public Students() {
}
public Students(String firstName, String lastName, String age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
#Column
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column
private String firstName;
#Column
private String lastName;
#Column
private String age;
#ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinTable(name = "Student_Course",
joinColumns = #JoinColumn(name="studentID"),
inverseJoinColumns = #JoinColumn(name="courseID"))
private List<Course> courses;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public List<Course> getCourses() {
return courses;
}
public void setCourses(List<Course> courses) {
this.courses = courses;
}
}
my Course Model :
package com.example.demo.models;
import javax.persistence.*;
import java.util.List;
#Entity
#Table
public class Course {
public Course() {
}
public Course(String courseName, String unitCount) {
this.courseName = courseName;
this.unitCount = unitCount;
}
#Column
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "CourseName")
private String courseName;
#Column
private String unitCount;
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinTable(name = "Student_Course",
joinColumns = #JoinColumn(name="courseID"),
inverseJoinColumns = #JoinColumn(name="studentID"))
private List<Students> students;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "teacherID")
private Teachers teachers;
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getUnitCount() {
return unitCount;
}
public void setUnitCount(String unitCount) {
this.unitCount = unitCount;
}
public List<Students> getStudents() {
return students;
}
public void setStudents(List<Students> students) {
this.students = students;
}
public Teachers getTeachers() {
return teachers;
}
public void setTeachers(Teachers teachers) {
this.teachers = teachers;
}
}
my Query in Service Layer:
#Transactional
public List<StudentInfo> getStudentInfo(){
Session session = sf.openSession();
Query hql = session.createQuery("select std.firstName, std.lastName, c.courseName from Students std join std.courses c");
var data = hql.list();
session.close();
return data;
}
and i want map query columns to this simple class :
package com.example.demo.ViewModels;
public class StudentInfo {
private String firstName;
private String lastName;
private String courseName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
}
and in finally..
my controller Class :
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView Index() {
List<StudentInfo> data = studentRepository.getAll();
return new ModelAndView("indexView", "data", data);
}
notice : i`m using thymeleaf in this project.
please help me.
thanks.:D
If you use Spring Data JPA you should be able to do it in the repository using the #Query annotation:
#Query(value = "SELECT new com.path.to.StudentInfo(std.firstName, " +
"std.lastName, c.courseName) " +
"FROM Students std join std.courses c"
List<StudentInfo> getAllStudentInfo();
Make sure you have an all-args constructor in StudentInfo though.
If you use Hibernate, it's almost the same:
entityManager.createQuery("SELECT new com.path.to.StudentInfo(std.firstName, " +
"std.lastName, c.courseName) " +
"FROM Students std join std.courses c",
StudentInfo.class)
Edit: I have concerns about whether it's supposed to work when using join, but give it a try regardless.

HQL compare existing Objects tables

I just want to explain following scenario.
I have Registration table for employee
It has one field like BranchAddress, and I have using table Branch for that with ManyToOne mapping.
#Entity
#Table(name = "temp_reg")
public class TemporaryRegistrationDTO {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int ID;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#ManyToOne(cascade=CascadeType.ALL)
private BranchDTO companyBranch;
public BranchDTO getCompanyBranch() {
return companyBranch;
}
public void setCompanyBranch(BranchDTO companyBranch) {
this.companyBranch = companyBranch;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
#Entity
#Table(name = "company_branch")
public class BranchDTO {
#Id
#GeneratedValue ( strategy = GenerationType.AUTO)
private int branchID;
public int getBranchID() {
return branchID;
}
public void setBranchID(int branchID) {
this.branchID = branchID;
}
#ManyToOne(cascade=CascadeType.ALL)
private CountriesDTO country;
#ManyToOne(cascade=CascadeType.ALL)
private StatesDTO state;
public CountriesDTO getCountry() {
return country;
}
public void setCountry(CountriesDTO country) {
this.country = country;
}
public StatesDTO getState() {
return state;
}
public void setState(StatesDTO state) {
this.state = state;
}
}
#Entity
#Table(name = "company_countries")
public class CountriesDTO {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private String countryCode;
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
private String countryName;
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
#Entity
#Table(name = "company_states")
public class StatesDTO {
#Id
#GeneratedValue ( strategy = GenerationType.AUTO)
private int state_id;
private String state;
private String stateCode;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
#Override
public String toString() {
return "StatesDTO [statesID=" + state_id + ", state=" + state + ", stateCode=" + stateCode + "]";
}
public int getState_id() {
return state_id;
}
public void setState_id(int state_id) {
this.state_id = state_id;
}
}
Now, What I want is that, whenever their is request for registration, Firstly I am checking if Branch Address is available in the Branch table. If it contains an entry already, then it will retrieve Branch row and stooping from same data to Branch Table
Now, to check for BranchDTO, I have created method in Branch Repository class.
#Query("from BranchDTO where country = :country and state = :state")
public BranchDTO existsEntry(#org.springframework.data.repository.query.Param("country") CountriesDTO country,#org.springframework.data.repository.query.Param("state") StatesDTO state);
But It reflects me following error,
object references an unsaved transient instance - save the transient instance before flushing: com.example.demo.pojo.CountriesDTO
Thank you guys

Hibernate Join Table

i have a MySQL database which is updated from Java with Entities.
I need a join table between two tables which contains 3 columns.
1 column from table Bar ("bar_id")
2 columns from table Owner ("owner_id", "bought")
Could you please tell me if that is possible or how I could realize that.
I want a join table which looks like this:
'bar_id' | 'owner_id' | 'bought'
--------------------------------
BaseEntity.java
#MappedSuperclass
public class BaseEntity {
private int id;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public int getId(){ return this.id; }
public void setId(int id){ this.id = id; }
}
Bar.java
#Entity
#Table(name="bar")
public class Bar extends BaseEntity{
private String name;
private String bought;
private List<Fan> fan;
private List<Owner> owner;
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="bought")
public String getBought() {
return bought;
}
public void setBought(String bought) {
this.bought = bought;
}
#ManyToMany(mappedBy="bar", targetEntity=Owner.class)
public List<Owner> getOwner() {
return owner;
}
public void setOwner(List<Owner> owner) {
this.owner = owner;
}
#ManyToMany
#JoinColumn(name="fan")
public List<Fan> getFan() {
return fan;
}
public void setFan(List<Fan> fan) {
this.fan = fan;
}
}
Owner.java
#Entity
#Table(name="owner")
public class Owner extends BaseEntity{
private String firstname;
private String lastname;
private String birthday;
private java.sql.Date bought;
private List<Bar> bar;
#Column(name="firstname")
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
#Column(name="lastname")
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
#Column(name="birthday")
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
#Column(name="bought")
public java.sql.Date getBought() {
return bought;
}
public void setBought(java.sql.Date bought) {
this.bought = bought;
}
#ManyToMany
#JoinColumn(name="bar")
public List<Bar> getBar() {
return bar;
}
public void setBar(List<Bar> bar) {
this.bar = bar;
}
}
You can create a Join table by the using #JoinTable annotation.
Please have a look at this post which explains how to achieve it.
How to create join table with JPA annotations?

JPA Entity being ignored

I'm trying to use JPA for the first time in a project. Most of my entities are working fine, but I am having trouble with one which is part of a Joined Inheritance Strategy.The entities are also being serialised by Jackson so they also have Json annotations.
The parent "User" class:
(Edit: added "Type" field)
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.WRAPPER_OBJECT)
#JsonTypeName("user")
#JsonSubTypes({
#JsonSubTypes.Type(name="customer", value=Customer.class),
#JsonSubTypes.Type(name="employee", value=Employee.class)})
#Entity(name = "User")
#Table(name="user")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(name="type",discriminatorType = DiscriminatorType.INTEGER)
#NamedQuery(name="User.all",query = "select u from User u")
public abstract class User {
#Id
private String username;
#Column(name = "type",nullable = false)
private int type;
public User(){
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public abstract Set<Order> getOrders();
}
A Child "Employee"
#JsonTypeName("employee")
#Entity(name="Employee")
#Table(name="employee")
#PrimaryKeyJoinColumn(name = "username",referencedColumnName = "username")
#DiscriminatorValue("1")
#NamedQuery(name = "Employee.all",query = "select e from Employee e")
public class Employee extends User implements Serializable{
private String username;
private String firstName;
private String lastName;
private String email;
#Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate dateStarted;
#Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate dateEnded;
#OneToMany(mappedBy = "employee",targetEntity = Order.class,fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
#JsonIgnore
private Set<Order> orders = new HashSet<>();
public Employee() {
}
#Override
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public void addOrder(Order order){
orders.add(order);
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public String getDateStarted() {
if(dateStarted != null)
return dateStarted.toString();
else return null;
}
public void setDateStarted(LocalDate dateStarted) {
this.dateStarted = dateStarted;
}
public String getDateEnded() {
if(dateEnded != null)
return dateEnded.toString();
else return null;
}
public void setDateEnded(LocalDate dateEnded) {
this.dateEnded = dateEnded;
}
#Override
public String toString(){
return getUsername();
}
}
And a child "Customer":
(Edit: removed #Id field)
#JsonTypeName("customer")
#Entity(name="Customer")
#Table(name="customer")
#PrimaryKeyJoinColumn(name = "username",referencedColumnName = "username")
#DiscriminatorValue("2")
#NamedQueries({
#NamedQuery(name="Customer.all",query = "select c from Customer c")
})
public class Customer extends User implements Serializable{
public enum VIP_TYPE {NORMAL,SILVER,GOLD,DIAMOND}
#Transient
private static final int SILVER_THRESHOLD = 1000;
#Transient
private static final int GOLD_THRESHOLD = 2000;
#Transient
private static final int DIAMOND_THRESHOLD = 3000;
private String firstName;
private String lastName;
private String email;
private String address;
private String postcode;
private String mobileNumber;
private String homeNumber;
#Convert(converter = VipTypeConverter.class)
private VIP_TYPE vipGroup;
private String discount;
#OneToMany(mappedBy = "customer",targetEntity = Order.class,fetch=FetchType.EAGER,cascade = CascadeType.ALL)
#JsonIgnore
private Set<Order> orders = new HashSet<>();
public Customer() {
}
#Override
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public void addOrder(final Order order){
orders.add(order);
updateVipGroup();
}
private void updateVipGroup() {
int sum = orders.stream().map(Order::getPayment).distinct().mapToInt(p->p.getAmmount()).sum();
if(sum > DIAMOND_THRESHOLD){
vipGroup = VIP_TYPE.DIAMOND;
return;
}
if(sum > GOLD_THRESHOLD){
vipGroup = VIP_TYPE.GOLD;
return;
}
if(sum > SILVER_THRESHOLD){
vipGroup = VIP_TYPE.SILVER;
return;
}
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setEmail(String email) {
this.email = email;
}
public void setAddress(String address) {
this.address = address;
}
public void setDiscount(String discount) {
this.discount = discount;
}
public void setVipGroup(VIP_TYPE vipGroup) {
this.vipGroup = vipGroup;
}
public void setHomeNumber(String homeNumber) {
this.homeNumber = homeNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public String getDiscount() {
return discount;
}
public VIP_TYPE getVipGroup() {
return vipGroup;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public String getAddress() {
return address;
}
public String getPostcode() {
return postcode;
}
public String getMobileNumber() {
return mobileNumber;
}
public String getHomeNumber() {
return homeNumber;
}
}
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="local" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/cod</jta-data-source>
<class>com.technicalpioneers.cod.user.Customer</class>
<class>com.technicalpioneers.cod.user.Employee</class>
<class>com.technicalpioneers.cod.user.User</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
Everything to do with "employee" works file, I can use the named query Employee.all to find all the employees in the database.
However, If I try to retrieve any customers I get errors. If I try to run the named query Customer.all I get:
java.lang.IllegalArgumentException: NamedQuery of name: Customer.all not found.
If I try to use EntityManager's find() method to find a particular customer I get:
javax.servlet.ServletException: Exception [EclipseLink-43] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [2] of type [class java.lang.Integer].
Descriptor: RelationalDescriptor(com.technicalpioneers.cod.user.User --> [DatabaseTable(user)])
I don't understand why the Customer entity is not being found by JPA. I've checked the user table and the "type" column is there with correct numbers, and #DescriminatorValue is set correctly. It's almost like the annotations are being ignored?
Have done many clean rebuilds and redeploys too. Any help would be very much appreciated!
I found this eventually. https://bugs.eclipse.org/bugs/show_bug.cgi?id=429992
It turns out EclipseLink will silently ignore entities with lambda expressions! Very annoying for it to not be at least mentioned in logs!
Thanks to everyone who took the time!

Categories

Resources