【问题标题】:One to one mapping in Hibernate?Hibernate中的一对一映射?
【发布时间】:2018-10-10 21:57:49
【问题描述】:

假设我们有两个数据库表InstructorInstructor_Details。它们具有一对一的关系,因此每个讲师可以有一个讲师详细信息,并且一个讲师详细信息仅与一位讲师相关联。

在纯数据库术语中,Instructor 表应该是Instructor_Details 表的父表,Instructor 表的主键应该作为Instructor_Details 表中的外键。

我正在学习 Hibernate,互联网上的大多数 @OneToOne 示例都修改了表,使得 Instructor_Details 主键用作 Instructor 表中的外键,这似乎与 Instructor 应该是矛盾的Instructor_Details 的父级。

如何以最佳方式实现这两个实体,以便我可以使用Instructor 的主键作为Instructor_Details 中的外键。另外请解释我想要的实现中的获取类型和级联。带有代码的示例将非常有帮助。

编辑

假设表格的属性如下:

Instructor(instructor_id (主键), first_name, last_name)

Instructor_Details(detail_id (主键)、dob、address、instructor_id (instructor table 的外键))

【问题讨论】:

  • 网络上有很多 JPA 1-1 关系的例子,不知道为什么你找不到与你认为正确的(你没有充分定义)相匹配的例子。 datanucleus.org:15080/products/accessplatform_5_2/jpa/… 如果Instructor 有一个InstructorDetails 对象(而InstructorDetails 没有Instructor 对象),那么FK 唯一合乎逻辑的位置是在拥有对象的表中...Instructor。如果关系是bidir,那么你可以选择哪一方有FK。
  • 我的全部观点是,由于InstructorDetails 的存在依赖于Instructor,所以Instructor 的主键应该在InstructorDetails 中,这将是理想的最佳数据库设计。我发现的所有示例都将InstructorDetails 的主键作为FK 放在Instructor 中,但从概念的角度来看,InstructorDetails 在这种情况下绝不应该是父键。我们不应该修改我们的数据库设计以适应 Hibernate 代码
  • @BillyFrost 谢谢这就是我想要的。本文解释了牢记 RDBMS 的映射。不幸的是我之前没有找到这个。谢谢

标签: java hibernate jpa orm


【解决方案1】:

由于在纯数据库术语中您将其建模为父/子,因此您被 OneToMany 卡住了。我在这种情况下所做的,所以我可以保持这样的关系并利用级联删除等功能。是在实体本身上有辅助方法。由于 Hibernate 使用反射,因此您实际上不需要为私有成员实现公共 getter 和 setter。

例如,您的 InstructorDetails Instructor 类的访问器可能如下所示:

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

    ...
}

有意义吗? add 也一样...您可以添加一个包含单个详细信息的添加,检查是否已经存在并覆盖或抛出,但在内部它处理列表。与Instructor 打交道的人永远不会知道里面有一个列表。

【讨论】:

  • 不,这不是我想要的。我想要一个@OneToOne 映射。这不是我想要的答案。
  • 只有一个与讲师相关联的讲师详细信息。所以这里没有教师详细信息列表。
  • @JotWaraich 我意识到这一点。这就是为什么您的父/子关系保留给使用InstructorInstructorDetails 作为“虚拟一对一”的人,您创建像getInstructorDetails() 这样的getter。它总是返回 1 InstructuorDetails,而不是列表。我 100% 理解你的问题。
  • 会有一个比这个使用@OneToOne@MapsId 注释的更优雅的解决方案。所以我不期待使用@OneToMany 的答案
猜你喜欢
  • 2021-08-18
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 2011-02-16
相关资源
最近更新 更多