java - Hibernate PostgreSQL OneToOne 关系首先触发子查询
问题描述
我正在构建应用程序来在 PostgreSQL 上学习 Hibernate。我目前正在尝试将变量添加到具有 OneToOne 关系的数据库中。
首先,我在我的数据库中创建了两个表,其架构如下。在person_detail
表上,它的主键也是person
表的外键。
然后我创建了两个类,Person
和PersonDetail
. PersonDetail
是Person
具有 OneToOne 关系的孩子。我使用下面的代码添加person
aspersonDetail
属性。
Person person = new Person(
"Rick",
1.7,
dateFromString("1969-4-2"),
new Date()
);
PersonDetail personDetail =
new PersonDetail("myemail@email.com", "Marley");
person.setPersonDetail(personDetail);
session.beginTransaction();
session.save(person);
session.save(personDetail);
session.getTransaction().commit();
System.out.println(person.toString());
但是上面代码的问题是Hibernate首先执行子查询而不是父查询。
Hibernate:插入person_detail(地址,电子邮件)值(?,?)
而且由于person
仍然是空的,我们不能插入任何行,person_detail
因为它违反了外键约束。
有没有办法解决这个问题?谢谢!
如果有人想检查我如何注释这两个类,我将代码放在下面。
@Entity
@Table(name="person")
@Data
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="name")
private String name;
@Column(name="height")
private double height;
@Column(name="birth_date")
private Date dateBirth;
@Column(name="last_seen")
private Date lastSeen;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id")
private PersonDetail personDetail;
public Person() {}
public Person(String name, double height, Date dateBirth, Date lastSeen){
this.name = name;
this.height = height;
this.dateBirth = dateBirth;
this.lastSeen = lastSeen;
}
}
@Data
@Entity
@Table(name="person_detail")
public class PersonDetail {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="email")
private String email;
@Column(name="address")
private String address;
public PersonDetail(){}
public PersonDetail(String email, String address){
this.email = email;
this.address = address;
}
}
解决方案
我看到你在表中有主键作为表person_details
的外键person
,你可以@PrimaryKeyJoinColumn
这样使用:
@Entity
@Table(name="person")
@Data
public class Person {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "height")
private String height;
@OneToOne(mappedBy = "person", cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private PersonDetail personDetail;
public Person() {}
public Person(String name, String height) {
this.name = name;
this.height = height;
}
}
@Data
@Entity
@Table(name="person_detail")
public class PersonDetail {
@Id
@Column(name="id")
private Long id;
@Column(name="email")
private String email;
@OneToOne
@MapsId
@JoinColumn(name = "id", referencedColumnName = "id")
private Person person;
public PersonDetail(){}
public PersonDetail(String email){
this.email = email;
}
}
如果您保存实体,请不要忘记将 Person 设置为 PersonDetails:
Person person = new Person("Rick", "1.7");
PersonDetail personDetail = new PersonDetail("myemail@email.com");
personDetail.setPerson(person);
person.setPersonDetail(personDetail);
repository.save(person);
推荐阅读
- python - 将线程限制在一定数量并通过列表
- android - 条纹样式的进度条?
- android - 来自谷歌的 install_referrer 邮件
- mysql - SQL 从超集中选择不相交的元素
- c# - 试图让用户控件加载 MainWindow 上可用的连接字符串(WPF,C# 相关)
- python - 为什么 Tkinter 不显示按钮?
- python - 通过 pip 安装 distorm3 会导致 Windows SDK 构建错误
- batch-file - Batch Echo Style:一次写入两个文件
- python - 变量资源管理器中的数据不可用于 Spyder 4 中的调试
- wpf - 有没有办法在 Microsoft.Xaml.Behaviors.Wpf 中使用 MVVMLight 的 EventToCommand?