在双向关系中从非所属对象触发保存方法时,在所属表中插入外键失败?



所以我有两个实体'Student'和'Parents',它们之间的关系是'OneToOne'。

此处为"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

数据库:POSTGRESQL

的学生表
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)

父母表

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)

注意:-

1)。我在两个表中使用uid_generate_v4()作为自动生成UUID

的默认值2.)学生表中的parent_id是引用父表主键的外键;

3)。这两个实体是双向关系。

我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();
}

}
}

所以如果我在我的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();

工作正常

Student table (owner side)


id                  |      name      |              parent_id
--------------------------------------+----------------+--------------------------------------
89879cd1-a562-48f3-8632-9eaa5d288f5f | Sinchan Nohara | 82206833-b0d0-4e99-94f5-cab32he8a361

父表(被引用方)

id                  |  father_name   | mother_name
--------------------------------------+----------------+--------------
82206833-b0d0-4e99-94f5-cab32he8a361 | Hiroshi Nohara | Missy Nohara

但是当我尝试运行下面给出的代码在我的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();

则student表中的外键(parent_id)没有被插入。

看下面的表格,

父母表

id                  |  father_name   | mother_name
--------------------------------------+----------------+--------------
380e4daa-0cba-4e26-aa3f-446dbc4fd2c0 | Hiroshi Nohara | Missy Nohara

的学生表
id                  |      name      | parent_id
--------------------------------------+----------------+-----------
de062q8d-ff58-4c05-a342-7uu67a4c842d | Sinchan Nohara |

为什么会这样?如何解决这个问题?

用hibernate处理双向关系是很棘手的。实际上,您的模型显示该关系属于student。当您定义关系时,仅设置parentsstudent以使其工作是不够的。您必须设置studentparents。这很棘手,因为当你加载studentparents时,你会得到两个对象的双向关系正确设置。当您创建、更新或删除时,问题就出现了。这就是关系的所有者变得重要的地方。顺便说一下,在您的情况下,我宁愿将parents设置为与student的关系的所有者,因为我想象,parents可能存在而没有student,而不是相反。

最新更新