Java JPA实体equals()方法的正确实现方式
我使用Eclipse通过选择感兴趣的字段/属性,为我的JPA实体生成了Java JPA实体equals()方法的正确实现方式,java,hibernate,jpa,Java,Hibernate,Jpa,我使用Eclipse通过选择感兴趣的字段/属性,为我的JPA实体生成了hashcode()和equals()方法 然而,我观察到Eclipse似乎在生成的equals方法中添加了以下行: if (getClass() != obj.getClass()) return false; 进行上述检查似乎合乎逻辑,但我在所有JPA实体中都使用了延迟加载关系,我注意到,在上述某些情况下,当obj的类是某种代理类且主要对象是所讨论的实体时,检查失败-我检查了被比较的对象的类,并且
hashcode()
和equals()
方法
然而,我观察到Eclipse似乎在生成的equals
方法中添加了以下行:
if (getClass() != obj.getClass())
return false;
进行上述检查似乎合乎逻辑,但我在所有JPA实体中都使用了延迟加载关系,我注意到,在上述某些情况下,当obj
的类是某种代理类且主要对象是所讨论的实体时,检查失败-我检查了被比较的对象的类,并且两者不完全相同,因此,上述条件的计算结果为false
,即使对象表示来自数据库的相同记录
因此,我的问题是,当我们为JPA实体实现
equals()
方法时,我们是否应该比较对象类。建议为JPA实体使用业务密钥equality。
自动生成的equals使用所有字段
您的实体很可能具有自动生成的技术主键(id字段)。在实体被持久化之后,该字段由数据库填充。
如果您有自动生成的equals/hashcode,那么它包括所有类字段——包括该id字段。
因此,实体的equals/hashcode将在持久化后更改,而不更改任何其他字段(持久化之前的id将为null,持久化之后的id将不为null)
有关更多详细信息,请阅读
这是Hibernate参考,但所有与主键相关的概念都应适用于任何JPA提供程序。通常,该检查用于防止出现
ClassCastException
。代理类和主实体类是否都有一个共同的父类可供您强制转换?我尝试将Student
类的实例与Student
类实例的集合进行比较-第一个实例从DB读取,而集合是延迟初始化的,因为它是与另一个实体的子关系的一部分,说College
,这并不能真正回答我的问题。您的代码在没有if
语句的情况下是否可以运行?如果是这样的话,您可以更宽松地使用instanceof
检查,而不是比较getClass()
。同时,我必须对此进行检查,其他人不也应该面对这个问题吗?因为我不确定我是否在处理延迟加载的实例时做了任何不寻常的事情。我认为,如果涉及代理,并且您想要一个通用的对象。equals
方法,您只能依赖instanceof
。对于同一类/类型的实体,Eclipse方式必须完全符合@Bartosz Bilicki,因为JPA实体是数据库行的唯一java视图。根据sql文档,主键约束唯一地标识数据库表中的每个记录。所以,如果您有两个具有相同ID的实体,这意味着它是相同的实体。我不使用类的所有字段/属性-在Eclipse中,当您使用选项Source->Generated equals和hashcode
时,它提供了一个GUI来选择将建立自然相等的字段。