How to fetch set of data using ID in hibernate if we have composite primary key? - mysql

I have Entities (Student,StudentSkills, StudentEmpSkills)
Student.java
#Entity
#Table(name = "Student", catalog = "dbs")
public class Student implements java.io.Serializable {
private int id;
...
...
private Set<StudentSkills> studentSkills= new HashSet<StudentSkills>(0);
private Set<StudentEmpSkills> studentEmpSkills= new HashSet<StudentEmpSkills>(0);
#OneToMany(fetch = FetchType.EAGER, mappedBy = "Student")
public Set<StudentSkills> getStudentSkills() {
return this.studentEmpSkills;
}
public void setStudentSkills(
Set<StudentSkills> studentSkills) {
this.studentSkills = studentSkills;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "Student")
public Set<StudentEmpSkills> getStudentEmpSkills() {
return this.StudentEmpSkills;
}
public void setStudentEmpSkills(
Set<StudentEmpSkills> studentEmpSkills) {
this.studentEmpSkills= studentEmpSkills;
}
}
in StudentEmpSkills.java
#Entity
#Table(name = "studentEmpSkills", catalog = "npdbs")
public class StudentEmpSkills implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private StudentEmpSkillsId id;
private Student Student ;
......
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "studentID", nullable = false, insertable = false, updatable = false)
public Student getStudent() {
return student;
}
In the above we are getting the Set of StudentEmpSkils from Student by one to many and many to one relation.
as we are getting Student from StudentEmpSkill
In JoinColumn we are giving studentID column to fetch the abject.
Now I want to get StudentSkill object from StudentEmpSkills.
StudentSkills - (studentID* | skillID*) | skillname
StudentEmpSkills - (studentID* | skillID* | empID*) | empName
(..) - composit primary key
So I want to fetch StudentSkills from StudentEmpSkill
What I need to write in StudentEmpSkills to fetch StudentSkill. because we have composit primary key in StudentSkill.
How to map the StudentSkill to StudentEmpSkills.
Can anyone please suggest?

Related

one to many and many to one mapping inserts null values in database

I have 3 model classes as UserBean , PolicyBean and RequestedPoliciesForUserBean.
userId is the primary key for userBean class.
policyNo is the primary key for PolicyBean class.
transactionId is the primary key for RequestedPoliciesForUserBean class.
The three model classes are as below with getter and setters (not showing getters and setters for better readability)
#Table(name="users")
public class UserBean {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY,generator = "native")
#GenericGenerator(name = "native",
strategy = "com.example.policymanagementsystem.idgenerator.UserIdGenerator",
parameters = {
#Parameter(name = UserIdGenerator.INCREMENT_PARAM, value = "50"),
#Parameter(name = UserIdGenerator.VALUE_PREFIX_PARAMETER,value="USER_"),
#Parameter(name = UserIdGenerator.NUMBER_FORMAT_PARAMETER, value ="%05d"),
})
#Column(name="userId")
private String userId;
#Size(min = 2 , max = 30, message = "must have atleast 2 characters and maximum 30")
#Column(name="name")
private String name;
#Column(name="age")
private String age;
#Column(name="city")
private String city;
#JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd")
#DateTimeFormat(pattern = "dd-MM-yyyy")
#Column(name="dateOfBirth")
private Date dateOfBirth;
#Size(max = 10 , message = "phone number must have 10 numbers")
#Column(name="phone")
private String phone;
#Email
#Column(name="email")
private String email;
#Pattern(regexp="^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!##&()–[{}]:;',?/*~$^+=<>]).{8,60}$", message = "password must have atleast 1 digit,1 upper case & 1 lower case letter,"
+ "1 special character,"
+ "no whitespace & minimum 8 & maximum 20 characters")
#NotNull(message="password cannot be null")
#Column(name="encodedPassword")
private String password;
#OneToMany(mappedBy = "users" , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<RequestedPoliciesForUserBean> requestedPoliciesForUserBean;
#NotNull(message = "role cannot be null")
#Column(name = "role")
#Enumerated(EnumType.STRING)
private Role role;
#Entity
#Table(name="policy")
public class PolicyBean {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY,generator = "native")
#GenericGenerator(name = "native",
strategy = "com.example.policymanagementsystem.idgenerator.PolicyIdGenerator",
parameters = {
#Parameter(name = PolicyIdGenerator.INCREMENT_PARAM, value = "50"),
#Parameter(name = PolicyIdGenerator.VALUE_PREFIX_PARAMETER,value="POLICY_"),
#Parameter(name = PolicyIdGenerator.NUMBER_FORMAT_PARAMETER, value ="%05d"),
})
#Column(name="policyNo")
private String policyNo;
#Size(min = 2 , max = 30, message = "must have atleast 2 characters and maximum 30")
#Column(name="planName")
private String planName;
#Min(value = 1, message = "tenure cannot be zero")
#Column(name="tenure")
private String tenure;
#OneToMany(mappedBy = "policy" , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<RequestedPoliciesForUserBean> requestedPoliciesForUserBean;
#Entity
#Table(name="requestedpoliciesforuser")
public class RequestedPoliciesForUserBean {
#GeneratedValue(strategy = GenerationType.IDENTITY,generator = "native")
#GenericGenerator(name = "native",
strategy = "com.example.policymanagementsystem.idgenerator.TransactionIdGenerator",
parameters = {
#Parameter(name = UserIdGenerator.INCREMENT_PARAM, value = "50"),
#Parameter(name = UserIdGenerator.VALUE_PREFIX_PARAMETER,value="TRANS_"),
#Parameter(name = UserIdGenerator.NUMBER_FORMAT_PARAMETER, value ="%05d"),
})
#Column(name="transactionId")
#Id
private String transactionId;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "userId", nullable = false)
private UserBean users;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "policyNo", nullable = false)
private PolicyBean policy;
#Column(name = "planName")
private String planName;
#Column(name = "tenure")
private String tenure;
#Enumerated(EnumType.STRING)
private PolicyStatus policyStatus;
I have three database tables as users, policy, requestedpoliciesforusers.
userId(primary key in users table) and policyNo(primary key in policy table) are the foreign keys references for requestedpoliciesforusers table.
One user can request for multiple policies and when user will request policy the data will get inserted in requestedpoliciesforusers table along with userId and policNo.Somewhat the scenario will be as below.
| User | Policy |
|------|--------|
| 1 | A |
| 1 | B |
| 2 | A |
| 3 | B |
| 1 | C |
But hibernate is inserting null values for userId and policyNo but all other fields are getting inserted properly. Below is the screenshot for the same.
My Postman request is as below:
{
"userId":"USER_02902",
"policyNo":"POLICY_00001",
"planName":"Recurring Deposit Plan",
"tenure":"20"
}
Please suggest why null values are getting inserted in database. Any changes required in one to many or many to one mapping. Thanks in Advance!
RequestedPoliciesForUserController
#RestController
#RequestMapping("/user")
public class RequestedPoliciesForUserController {
#Autowired
private RequestedPoliciesForUserService requestedPoliciesForUserService;
#PutMapping(path="/policy/request",consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public PolicyResponses requestPolicy(#RequestBody RequestedPoliciesForUserBean requestedPoliciesForUser) {
PolicyResponses policyResponses = new PolicyResponses();
boolean isPolicyRequested = requestedPoliciesForUserService.requestPolicy(requestedPoliciesForUser);
if(isPolicyRequested) {
policyResponses.setStatusCode(200);
policyResponses.setMessage("request sent");
policyResponses.setDescription("Policy request sent successfully");
}
return policyResponses;
}
}
RequestedPoliciesForUserServiceImpl
#Service
public class RequestedPoliciesForUserServiceImpl implements RequestedPoliciesForUserService {
#Autowired
RequestedPoliciesForUserDAO requestedPoliciesForUserDAO;
#Override
public boolean requestPolicy(RequestedPoliciesForUserBean requestedPoliciesForUserBean) {
// TODO Auto-generated method stub
return requestedPoliciesForUserDAO.requestPolicy(requestedPoliciesForUserBean);
}
}
RequestedPoliciesForUserDAOImpl
#Repository
public class RequestedPoliciesForUserDAOImpl implements RequestedPoliciesForUserDAO {
#PersistenceUnit
private EntityManagerFactory entityManagerFactory;
#Override
public boolean requestPolicy(RequestedPoliciesForUserBean requestedPoliciesForUserBean) {
EntityManager entityManager = null;
EntityTransaction entityTransaction = null;
boolean isPolicyRequested = false;
try {
entityManager=entityManagerFactory.createEntityManager();
entityTransaction=entityManager.getTransaction();
entityTransaction.begin();
System.out.println(requestedPoliciesForUserBean);
requestedPoliciesForUserBean.setPolicyStatus(PolicyStatus.PENDING);
entityManager.persist(requestedPoliciesForUserBean);
entityTransaction.commit();
entityManager.close();
isPolicyRequested =true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
} // end of requestPolicy()
}
Postman Response
{
"statusCode": 0,
"message": null,
"description": null,
"policyList": null
}
Create PK argument constructor in both the PolicyBean and UserBean classes. Also, the request in postman is not matching the RequestedPoliciesForUserBean. You pass userId and the class has users, policyNo and the class have policy.
UserBean constructor:
public UserBean(String userId) {
this.userId = userId;
}
PolicyBean constructor:
public PolicyBean(String policyNo) {
this.policyNo = policyNo;
}
Change your request JSON to:
{
"users": "USER_02902",
"policy": "POLICY_00001",
"planName": "Recurring Deposit Plan",
"tenure": "20"
}
It will save data in all columns of your requestedpoliciesforuser table. Also instead of using entitymanager directly use JPA. Spring Data JPA

How to define composite foreign key mapping in hibernate?

I have two tables: users and userdetails as follows:
package com.example.easynotes.model;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name = "users")
#IdClass(UserID.class)
public class User implements Serializable {
#Id
int id;
#Id
String name;
String department;
//getters and setters
}
The userdetails classes will be this:
public class UserDetails implements Serializable{
int id;
String name;
String address;
String otherFields;
//getters and setters
}
id and name in users is a composite primary and I want the same fields in userdetails to be the foreign key. How can I achieve this in hibernate ?
We need to put both key in #Embeddable to detach compound key thenafter, put it in User Entity using #EmbeddedId and map both primary key using Hibernate Relational Mapping...
There are two option to Composite Primary Key:
Using #EmbeddedId
Using #IdClass()
Here down is example:
----------------------------------- Using EmbeddedId -----------------------------------
Compound primary key:
#Embeddable
public class UserIdName implements Serializable {
int id;
String name;
// getter and setter
}
User:
#Entity
#Table(name = "users")
public class USER{
#EmbeddedId
private UserIdName id;
String department;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Userdetail> userdetail;
// getter and setter
}
UserDetails:
#Entity
#Table(name = "Userdetail")
public class Userdetail {
#Id
private int detail_id;
#ManyToOne
#JoinColumns({ #JoinColumn(name = "id", referencedColumnName = "id"),
#JoinColumn(name = "name", referencedColumnName = "name") })
private USER user;
String address;
String otherFields;
// getter setter
}
----------------------------------- Using IdClass -----------------------------------
Compound primary key:
public class UserIdName implements Serializable {
int id;
String name;
// getter and setter
}
User:
#Entity
#Table(name = "users")
#IdClass(UserIdName.class)
public class USER{
#Id
int id;
#Id
String name;
String department;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Userdetail> userdetail;
// getter and setter
}
UserDetails:
#Entity
#Table(name = "Userdetail")
public class Userdetail {
#Id
private int detail_id;
#ManyToOne
#JoinColumns({ #JoinColumn(name = "id", referencedColumnName = "id"),
#JoinColumn(name = "name", referencedColumnName = "name") })
private USER user;
String address;
String otherFields;
// getter setter
}
-> If you wanna insert both foreign key manually try below code
Put this code in UserDetails
#ManyToOne
#JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
#JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
private USER user;
#Column(name="id")
private int id;
#Column(name="name")
private String name
// don't forget to put getter setter
User Table:
User Detail Table:

Indexing for key which belongs to Primary key of other table

I have a two table as table as
#Entity
#Table(name = "product", uniqueConstraints=#UniqueConstraint(columnNames={"product_idn"}))
public class Product implements Serializable {
private static final long serialVersionUID = 21409635044L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String product_idn;
}
another table as
#Entity
#Table(name = "storage")
public class Storage implements Serializable {
private static final long serialVersionUID = -67165579239L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "product_id", nullable = false)
#JsonBackReference
private Product product;
}
Now I am fetching record from storage table. Should create a index (Non-Unique)on product_id of storage table? I have to fetch storages count per on product/ featching storages based on product.
Just add #Index annoation like below and it should work fine.
#Entity
#Table(name = "storage", indexes = #Index(columnList = "product_id",name = "storage_productId_index"))
public class Storage implements Serializable

How can I use post method data in back end to save many to many relationship data with #JsonIgnore annotation.My joining table is not updating

How can I use the data send through post method, and save those data in a many to many relationship? I used #JsonIgnore annotation to stop the recursion.
I have implemented two entities.One is Employee and the other is Skills.In the Employee entity I used #JsonIgnore annotation to avoid the reccursion. But when I inserted the values Employee table got updated but the joining tabled is not updating.
This is my Employee entity class
#Entity
#Table(name = "Employee")
public class Employee implements Serializable{
private static final long serialVersionUID = -3009157732242241606L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long emp_id;
#Column(name = "emp_fname")
private String emp_fname;
#Column(name = "emp_lname")
private String emp_lname;
#Column(name = "emp_email")
private String emp_email;
#Column(name = "emp_dob")
private Date emp_dob;
#ManyToMany(cascade = CascadeType.MERGE)
#JoinTable(name = "emp_skills",
joinColumns = #JoinColumn(name = "emp_id", referencedColumnName = "emp_id"),
inverseJoinColumns = #JoinColumn(name = "s_id",referencedColumnName = "s_id"))
#JsonIgnore
private Set<Skills> skills;
}
This is my Skills class
#Entity
#Table(name = "Skills")
public class Skills implements Serializable {
private static final long serialVersionUID = -3009157732242241606L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long s_id;
#Column(name = "s_name")
private String s_name;
#ManyToMany(mappedBy = "skills")
private Set<Employee> employees;
And this is my controller class method to save data
#RequestMapping("/save")
#PostMapping("/save")
#CrossOrigin
public void createEmployee(#RequestBody Employee employee, BindingResult bindingResult){
Employee emp = new Employee(employee.getEmp_fname(),employee.getEmp_lname(),employee.getEmp_email(),employee.getEmp_dob());
emp.setSkills(employee.getSkills());
empRepository.save(emp);
//empRepository.save(new Employee(employee.getEmp_fname(),employee.getEmp_lname(),employee.getEmp_email(),employee.getEmp_dob()));
}
I want to update both Employee and emp_skills (the joining table) when the save method is triggered.

path expected for join JPA Hibernate MySQL

I'm using composite PK in my app with 2 tables and one joining table.
I wrote this query for function:
#Repository
public interface HospitalDoctorDao extends JpaRepository<HospitalDoctor, Integer>{
#Query("select hd from HospitalDoctor hd join hospital on hd.hospital_id=hospital.id join doctor on hd.doctor_id = doctor.id where hospital_id = ?1 and doctor_id = ?1")
HospitalDoctor findByHospitalIdAndDoctorId(int hospital_id, int doctor_id);
}
and I am getting error Path expected for file! In MySQL everything is working. How Hibernate works in this case? How I should write this query? Here is my #Entity of join table:
#Entity
#Table(name = "hospital_doctor")
public class HospitalDoctor {
#Embeddable
static class HosdocPK implements Serializable {
private int hospitalId;
private int doctorId;
}
#EmbeddedId
#JsonBackReference
public HosdocPK hosdocPK;
#JsonManagedReference
#MapsId("DoctorId")
#ManyToOne(optional = false)
#JoinColumn(name = "doctorId", referencedColumnName = "id")
private Doctor doctor;
#JsonManagedReference
#MapsId("HospitalId")
#ManyToOne(optional = false)
#JoinColumn(name = "hospitalId", referencedColumnName = "id")
private Hospital hospital;
#Column(name = "Id")
private int id;
#Temporal(TemporalType.DATE)
private Date contract_start_date;
#Temporal(TemporalType.DATE)
private Date contract_end_date;
private String position;
private String supervisor;
private boolean part_time;
Getters and setters
}
Your query is incorrect.
Try:
select hd from HospitalDoctor hd where hd.hospital.id = ?1 and hd.doctor.id = ?2