Hibernate对象标识

时间:2009-08-02 20:02:19

标签: java hibernate

在使用Hibernate的Java持久性中,gavin建议我们使用业务键进行相等性比较。业务密钥不仅可以涉及多个字段比较,而且无法保证“完美”业务密钥的语义在将来不会发生变化。我们生活在非理想的世界,商业要求和法律经常变化。在这种情况下,我们将在数据库中留下存储多个业务键语义的数据。我想将问题分成两部分:

  1. 当我们严格处理持久或分离的对象时。
  2. 当我们处理瞬态物体时。

  3. 如果我们处理持久和分离的对象,我仍然没有看到使用代理键进行相等和哈希码的任何缺点。如果两个持久对象具有相同的主键,则它们是等于的。这是错误的假设吗?

  4. 当我们处理瞬态对象时,我们可以使用业务键语义来比较对象,并且如果您尝试使用相同的业务键但在剩余属性中保留两个具有不同值的临时对象,则可以使用合并策略。 / p>

  5. 在读取繁重的应用程序中,大多数事务都是读取/更新的,这种策略应该会产生更好的性能。

2 个答案:

答案 0 :(得分:1)

对象标识和Hibernate的问题与瞬态对象有关:何时创建主键?如果您在写入数据库时​​使用了答案(使用DB控制的主键生成,例如Oracle序列),那么您就有潜在的问题。

如果主键用作等式检查的基础,并且它是哈希码生成的一部分,那么您将破坏哈希码契约,因为在生成主键之前和之后对象将不相同。 / p>

如果可以,只需使用您可以在对象创建时设置的生成主键(例如UUID)。这可确保您的哈希代码和相等性检查保持一致。

答案 1 :(得分:1)

我过去常常为每个班级找到完美的商业密钥而烦恼,并且最终会在没有任何可能永远无法改变的独特之处的情况下使用UUID。但是现在,我使用数据库代理键并避免我必须依赖于瞬态对象的相等性的情况。它似乎更简单,更不容易出错,而且速度更快。它可能取决于应用程序的类型,但对于典型的CRUD应用程序,该对象通常会在您必须在集合中处理它之前进入数据库。