【问题标题】:Object equality/hashcode vs JPA/Hibernate entity equality/hashcode对象相等/哈希码与 JPA/Hibernate 实体相等/哈希码
【发布时间】:2020-11-25 11:02:12
【问题描述】:

在阅读了一些关于该主题的内容后,我对 @Entity 相等性的 Hibernate/JPA 要求有点迷茫。我真的需要调整我的@EqualsAndHashCode 以使我的实体在 2020 年仍然基于数据库唯一性相等吗?那么@Id 元注释的意义何在?

我需要能够在对象级别比较我的实体,所以现在我只是根据@Id 之外的所有字段实现了我的 EqualsAndHashCode。

如果我继续采用这种方法,我会面临哪些问题?如果由于某种原因Hibernate尝试存储或混合具有相同@Id但与我的实现不相等的2个实体,那么数据库是否会抛出异常?真的有风险吗?我很确定我在过去看到过很多经过适当测试的项目,没有人定义任何特定的@EqualsAndHashCode,所以默认情况下只是比较实例,这些项目通过了各种绿色的 CRUD 测试,并且在生产中没有错误

【问题讨论】:

    标签: java hibernate jpa spring-data-jpa spring-data


    【解决方案1】:

    基本上,当实体之间存在双向关系时,您会遇到一些问题。例如,如果 Entity1 对 Entity2 具有 @OneToMany 访问权限,而 Entity2 对 EntityId 具有 @ManyToOne 访问权限,并且这两个实体都具有 @EqualsAndHashcode 而没有指定字段(即,为所有字段生成 equalshashcode包括那些用于关系的)。在这种情况下,您会有一个循环引用,因此会出现 StackOverflow 异常。

    为了避免这种情况,您只能依赖带有@Id 的字段来构造equalshashcode(在hibernate 文档中有一些使用这种方法的示例)。但在这种情况下,你会遇到另一种问题,例如如果您将具有自动生成的 id 的临时实体存储在一组中(作为某些父实体的子实体),它将无法正常工作,因为在这种情况下 id 字段将为null。在这种情况下,您可能需要使用 equalshashcode 中的其他字段。

    所以,这个问题没有正确答案。每次构建实体时都需要做出决定。

    【讨论】:

    • 感谢您的回答,目前,我选择了第一种方法并通过放置 EqualsAndHashCode.Includes 来修复循环依赖。和 EqualsAndHashCode.Excludes,不包括关系对象并包括只考虑本地表 FK 字段 id 的自定义 getter。我没有任何自动生成的字段,所以我认为我玩得很安全
    • 是的,我倾向于在我的代码中做几乎相同的事情。我想补充一点,由于 Lombok 的 @ToString 注释也会出现同样的“循环”问题,所以不要忘记也为这个注释添加排除项(如果你使用它)。
    • 无论如何,我不确定这个答案是否完整,或者我们排除这不适用于docs.jboss.org/hibernate/stable/core.old/reference/en/html/…thorben-janssen.com/…
    猜你喜欢
    • 2011-10-21
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2020-06-22
    • 1970-01-01
    相关资源
    最近更新 更多