Java Hibernate中的一对一映射?
假设我们有两个数据库表Java Hibernate中的一对一映射?,java,hibernate,jpa,orm,Java,Hibernate,Jpa,Orm,假设我们有两个数据库表讲师和讲师详细信息。它们具有一对一关系,这样每个讲师都可以有一个讲师详细信息,并且一个讲师详细信息仅与一个讲师关联 在纯数据库术语中,讲师表应该是讲师详细信息表的父项,讲师表的主键应该用作讲师详细信息表中的外键 我在学习Hibernate,互联网上的大多数@OneToOne示例都修改了表,使得讲师详细信息主键在讲师表中用作外键,这似乎是矛盾的,因为讲师应该是讲师详细信息的父项 如何以最佳方式实现这两个实体,以便在讲师详细信息中使用讲师的主键作为外键。另外,请在我想要的实现中
讲师
和讲师详细信息
。它们具有一对一关系,这样每个讲师都可以有一个讲师详细信息,并且一个讲师详细信息仅与一个讲师关联
在纯数据库术语中,讲师
表应该是讲师详细信息
表的父项,讲师
表的主键应该用作讲师详细信息
表中的外键
我在学习Hibernate,互联网上的大多数@OneToOne
示例都修改了表,使得讲师详细信息
主键在讲师
表中用作外键,这似乎是矛盾的,因为讲师
应该是讲师详细信息
的父项
如何以最佳方式实现这两个实体,以便在讲师详细信息中使用讲师
的主键作为外键。另外,请在我想要的实现中解释获取类型和级联。带有代码的示例将非常有用
编辑
假设表的属性如下所示:
讲师(讲师id(主键)、名、姓)
讲师详细信息(详细信息id(主键)、dob、地址、讲师id(讲师表中的外键))因为在纯数据库术语中,您将其建模为家长/孩子,您只能使用OneToMany。在这种情况下,我所做的就是在实体本身上使用helper方法,这样我就可以保持这样的关系,并利用级联删除等功能。因为Hibernate使用反射,所以实际上不需要为私有成员实现公共getter和setter
因此,例如,讲师的访问者详细信息讲师
类可以如下所示:
public class Instructor {
...
@OneToMany
private List<InstructorDetails> instructorDetails;
public Optional<InstructorDetails> getInstructorDetails() {
if (instructorDetails == null || instructorDetails.size() == 0) {
return Optional.empty();
} else if (instructorDetails.size() > 1) {
// Optional raise if you want to be aware of corrupt Instructors that have many details
throw Exception("There's corrupt data");
} else {
return Optional.of(instructorDetails.get(0));
}
}
...
}
公共课堂讲师{
...
@独身癖
私人名单或详细资料;
公共可选getInstructorDetails(){
if(instructorDetails==null | | instructorDetails.size()==0){
返回可选的.empty();
}else if(instructorDetails.size()>1){
//如果你想知道有很多细节的腐败讲师,可以选择加薪
抛出异常(“有损坏的数据”);
}否则{
返回可选的.of(instructorDetails.get(0));
}
}
...
}
有道理吗?相同的添加。。。您可以有一个add,它接受单个细节,检查是否已经有一个细节,并覆盖或抛出,但在内部它处理列表。无论是谁与讲师打交道
都不会知道里面有一张清单。因为在纯粹的数据库术语中,您将其建模为家长/孩子,而您却被困在了一家公司。在这种情况下,我所做的就是在实体本身上使用helper方法,这样我就可以保持这样的关系,并利用级联删除等功能。因为Hibernate使用反射,所以实际上不需要为私有成员实现公共getter和setter
因此,例如,讲师的访问者详细信息讲师
类可以如下所示:
public class Instructor {
...
@OneToMany
private List<InstructorDetails> instructorDetails;
public Optional<InstructorDetails> getInstructorDetails() {
if (instructorDetails == null || instructorDetails.size() == 0) {
return Optional.empty();
} else if (instructorDetails.size() > 1) {
// Optional raise if you want to be aware of corrupt Instructors that have many details
throw Exception("There's corrupt data");
} else {
return Optional.of(instructorDetails.get(0));
}
}
...
}
公共课堂讲师{
...
@独身癖
私人名单或详细资料;
公共可选getInstructorDetails(){
if(instructorDetails==null | | instructorDetails.size()==0){
返回可选的.empty();
}else if(instructorDetails.size()>1){
//如果你想知道有很多细节的腐败讲师,可以选择加薪
抛出异常(“有损坏的数据”);
}否则{
返回可选的.of(instructorDetails.get(0));
}
}
...
}
有道理吗?相同的添加。。。您可以有一个add,它接受单个细节,检查是否已经有一个细节,并覆盖或抛出,但在内部它处理列表。任何与讲师打交道的人
都不会知道里面有一张名单。不,这不是我想要的。我想要一个@OneToOne映射。这不是我想要的答案。只有一个讲师详细信息与讲师相关。所以这里没有必要列出讲师的详细信息。@JotWaraich我意识到这一点。这就是为什么您的父/子关系与使用讲师
和讲师详细信息
作为“虚拟1对1”的人保持一致,您可以创建这样的gettergetInstructorDetails()
。它始终返回1个InstructuOrderDetails,而不是列表。我100%理解你的问题。将有一个比这个更优雅的解决方案,它将使用@OneToOne
和@MapsId
注释。因此,我不希望使用@OneToMany
得到答案。不,这不是我想要的。我想要一个@OneToOne映射。这不是我想要的答案。只有一个讲师详细信息与讲师相关。所以这里没有必要列出讲师的详细信息。@JotWaraich我意识到这一点。这就是为什么您的父/子关系与使用讲师
和讲师详细信息
作为“虚拟1对1”的人保持一致,您可以创建这样的gettergetInstructorDetails()
。它始终返回1个InstructuOrderDetails,而不是列表。我100%理解你的问题。将有一个比这个更优雅的解决方案,它将使用@OneToOne
和@MapsId
注释。因此,我并不期待使用@OneToMany
得到答案。网上有很多JPA 1-1关系的例子,不知道为什么你找不到一个与你认为正确的(你没有充分定义)相匹配的。如果讲师
有讲师详情
对象(而讲师详情
没有讲师
对象),则