So I have Two entities 'Student' and 'Parents' and the relationship between them is of 'OneToOne'.
Owning side here is 'student'.
Student.java
import java.util.UUID;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
@Entity
@Table(name="student")
public class Student {
@Id
@Column(name="id")
@GeneratedValue(generator="pg-uuid",strategy=GenerationType.AUTO)
@Type(type = "org.hibernate.type.PostgresUUIDType")
private UUID id;
@Column(name="name")
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="parent_id")
private Parents parents;
Student(){
}
Student(String name){
this.name=name;
}
//Getters And Setters
Parents.java
import java.util.UUID;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
@Entity
@Table(name="parents")
public class Parents {
@Id
@Column(name="id")
@GeneratedValue(generator="pg-uuid",strategy=GenerationType.AUTO)
@Type(type = "org.hibernate.type.PostgresUUIDType")
private UUID id;
@Column(name="father_name")
private String fatherName;
@Column(name="mother_name")
private String motherName;
@OneToOne(mappedBy = "parents",cascade = CascadeType.ALL)
private Student student;
public Parents() {
}
public Parents(String fatherName,String motherName) {
this.fatherName=fatherName;
this.motherName = motherName;
}
//Getter and Setters
Database : POSTGRESQL
Student table
Column | Type | Collation | Nullable | Default
-----------+-----------------------+-----------+----------+--------------------
id | uuid | | not null | uuid_generate_v4()
name | character varying(50) | | |
parent_id | uuid | | |
Indexes:
"student_pkey" PRIMARY KEY, btree (id)
"student_parent_id_key" UNIQUE CONSTRAINT, btree (parent_id)
Foreign-key constraints:
"student_parent_id_fkey" FOREIGN KEY (parent_id) REFERENCES parents(id)
Parents table
Column | Type | Collation | Nullable | Default
-------------+-----------------------+-----------+----------+--------------------
id | uuid | | not null | uuid_generate_v4()
father_name | character varying(80) | | not null |
mother_name | character varying(80) | | not null |
Indexes:
"parents_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "student" CONSTRAINT "student_parent_id_fkey" FOREIGN KEY (parent_id) REFERENCES parents(id)
Note:-
1.) I'm using uuid_generate_v4() as default in both the tables for auto generating UUID
2.)parent_id in the student table is the foreign key that has reference for parents table primary key;
3.) Both the entities are in a bidirectional relationship.
My StudentApp.java
public class StudentApp {
public static void main(String args[])
{
SessionFactory factory=new Configuration()
.configure()
.addAnnotatedClass(Student.class)
.addAnnotatedClass(Parents.class)
.buildSessionFactory();
Session session=factory.getCurrentSession();
try {
Student student=new Student("Sinchan Nohara");
Parents parents=new Parents("Hiroshi Nohara","Missy Nohara");
student.setParents(parents);
session.beginTransaction();
session.save(student)
session.getTransaction().commit();
}
catch(Exception e){
e.printStackTrace();
}
finally{
session.close();
factory.close();
}
}
}
So if I run the code given below in my StudentApp.java
Student student=new Student("Sinchan Nohara");
Parents parents=new Parents("Hiroshi Nohara","Missy Nohara");
student.setParents(parents);
session.beginTransaction();
session.save(student)
session.getTransaction().commit();
its working fine .
Student table (Owning side)
id | name | parent_id
--------------------------------------+----------------+--------------------------------------
89879cd1-a562-48f3-8632-9eaa5d288f5f | Sinchan Nohara | 82206833-b0d0-4e99-94f5-cab32he8a361
Parents Table (Referenced Side)
id | father_name | mother_name
--------------------------------------+----------------+--------------
82206833-b0d0-4e99-94f5-cab32he8a361 | Hiroshi Nohara | Missy Nohara
But when I try to run the code given below in my StudentApp.java
Student student=new Student("Sinchan Nohara");
Parents parents=new Parents("Hiroshi Nohara","Missy Nohara");
parents.setStudent(student);
session.beginTransaction();
session.save(parents)
session.getTransaction().commit();
then the foreign key(parent_id) in the student table is not getting inserted.
look at the tables below now,
Parents table
id | father_name | mother_name
--------------------------------------+----------------+--------------
380e4daa-0cba-4e26-aa3f-446dbc4fd2c0 | Hiroshi Nohara | Missy Nohara
Student Table
id | name | parent_id
--------------------------------------+----------------+-----------
de062q8d-ff58-4c05-a342-7uu67a4c842d | Sinchan Nohara |
Why this is happening? and how to fix it?
Dealing with bidirectionnal relations with hibernate is tricky. In fact, your model shows that the relation is owned by the
student
. When you define the relation, it is not enough to set thestudent
of aparents
to make it work. You have to set theparents
of thestudent
. This is tricky because when you load astudent
or aparents
you will get both objects with their bidirectional relation properly set. The problems arise when you do create, update or delete. That's where the owner of the relation becomes important. By the way, in your case, I would rather set theparents
as the owner of the relation to thestudent
since, I imagine,parents
may exist withoutstudent
and not the opposite.