gpt4 book ai didi

java - hibernate/webapp 上下文中的对象相等性

转载 作者:搜寻专家 更新时间:2023-10-30 21:07:19 25 4
gpt4 key购买 nike

如何处理由 hibernate 管理的 java 对象的对象相等性?在“hibernate in action”一书中,他们说人们应该更喜欢业务键而不是代理键。
大多数时候,我没有业务 key 。想想映射到一个人的地址。地址保存在一个集合中并显示在 Wicket RefreshingView 中(使用 ReuseIfEquals 策略)。

我可以使用代理 ID 或使用 equals() 和 hashCode() 函数中的所有字段。
问题是这些字段在对象的生命周期内会发生变化。要么是因为用户输入了一些数据,要么是由于在 OSIV(在 View 中打开 session )过滤器中调用了 JPA merge() 而导致 id 发生了变化。

我对 equals() 和 hashCode() 契约的理解是,它们在对象的生命周期内不应更改。

到目前为止我已经尝试过:

  • equals() 基于 hashCode(),它使用数据库 id(如果 id 为 null,则为 super.hashCode())。问题:新地址以 null id 开头,但在附加到一个人时获得一个 id,并且这个人在 osiv-filter 中被合并()(重新附加)。
  • 在首次调用 hashCode() 时延迟计算哈希码,并将该哈希码设为 @Transitional。不起作用,因为 merge() 返回一个新对象并且哈希码没有被复制。

我认为我需要的是一个在对象创建期间分配的 ID。我在这里有什么选择?我不想介绍一些额外的持久属性。有没有办法显式地告诉 JPA 为对象分配一个 ID?

问候

最佳答案

使用实体的 id 不是一个好主意,因为 transient 实体还没有 id(并且您仍然希望 transient 实体可能等于持久实体)。

使用所有属性(除了数据库标识符)也不是一个好主意,因为所有属性都不是身份的一部分。

因此,实现相等性的首选(也是正确)方法是使用业务 key ,如 Java Persistence with Hibernate 中所述:

Implementing equality with a business key

To get to the solution that we recommend, you need to understand the notion of a business key. A business key is a property, or some combination of properties, that is unique for each instance with the same database identity. Essentially, it’s the natural key that you would use if you weren’t using a surrogate primary key instead. Unlike a natural primary key, it isn’t an absolute requirement that the business key never changes—as long as it changes rarely, that’s enough.

We argue that essentially every entity class should have some business key, even if it includes all properties of the class (this would be appropriate for some immutable classes). The business key is what the user thinks of as uniquely identifying a particular record, whereas the surrogate key is what the application and database use.

Business key equality means that the equals() method compares only the properties that form the business key. This is a perfect solution that avoids all the problems described earlier. The only downside is that it requires extra thought to identify the correct business key in the first place. This effort is required anyway; it’s important to identify any unique keys if your database must ensure data integrity via constraint checking.

For the User class, username is a great candidate business key. It’s never null, it’s unique with a database constraint, and it changes rarely, if ever:

    public class User {
...
public boolean equals(Object other) {
if (this==other) return true;
if ( !(other instanceof User) ) return false;
final User that = (User) other;
return this.username.equals( that.getUsername() );
}
public int hashCode() {
return username.hashCode();
}
}

也许我错过了什么,但对于地址,业务 key 通常由街道号码、街道、城市、邮政编码和国家/地区组成。我认为这没有任何问题。

以防万一,Equals And HashCode是另一本有趣的读物。

关于java - hibernate/webapp 上下文中的对象相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2719877/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com