问题描述
在Hibernate中应该如何实现模型类的equals和hashcode?常见的缺陷是什么?大多数情况下,默认实现是否足够好?是否有任何意义使用业务密钥?在我看来,很难在任何情况下都能正确工作,例如懒惰抓取,身份证生成,代理等等。
如果你的实体是 Set 的一部分,或者你将要分离/附加它的实例,你只需要担心它。后者并不常见。前者通常最好通过以下方式处理:
- 基于 equals() / <$商业密钥上的c $ c> hashCode() - 例如在对象(或者至少会话)生命周期中不会改变的独特属性组合。
- 如果上述不可能,base equals() / 主键上的hashCode()如果它已设置且对象标识/ System.identityHashCode()$ c $否则。这里的重要的部分是您需要重新加载新实体添加到其中并保留后的Set;否则最终会出现奇怪的行为(最终导致错误和/或数据损坏),因为您的实体可能被分配给与其当前 hashCode()不匹配的存储桶。
How should model class's equals and hashcode be implemented in Hibernate? What are the common pitfalls? Is the default implementation good enough for most cases? Is there any sense to use business keys?
It seems to me that it's pretty hard to get it right to work in every situation, when lazy fetching, id generation, proxy, etc are taken into account.
Hibernate has a nice and long description of when / how to override equals() / hashCode() in documentation
The gist of it is you only need to worry about it if your entity will be part of a Set or if you're going to be detaching / attaching its instances. The latter is not that common. The former is usually best handled via:
- Basing equals() / hashCode() on a business key - e.g. a unique combination of attributes that is not going to change during object (or, at least, session) lifetime.
- If the above is impossible, base equals() / hashCode() on primary key IF it's set and object identity / System.identityHashCode() otherwise. The important part here is that you need to reload your Set after new entity has been added to it and persisted; otherwise you may end up with strange behavior (ultimately resulting in errors and / or data corruption) because your entity may be allocated to a bucket not matching its current hashCode().
这篇关于在使用JPA和Hibernate时如何实现equals和hashcode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!