3

有很多问题与如何实现由 Hibernate 管理的实体的良好 equals 和 hashcode 函数有关。但是,我没有找到任何解决我的问题的方法:

我有一个没有业务密钥的实体类。它有一个生成的主键、一些不能用于标识的属性以及与其他实体类的多个关联。我总是尝试坚持 Hibernate 的建议(业务密钥的平等),所以我不想检查生成的 Id。这导致检查 2 个唯一标识我的实体类的关联。但这会导致这两个关联必须定义为 FetchType.EAGER。

对于我的 equals 函数,我可以考虑其他替代方法吗?


更新:

您如何看待 Hibernate 中“通用”equals 方法的以下解决方案?

public boolean equals(Object object) {
    if (this == object) return true;
    if (! (object instanceof AbstractEntity)) return false;

    AbstractEntity other = (AbstractEntity) object;

    if (getId() == null && other.getId() != null) return false;
    if (getId() != null && other.getId() == null) return false;
    if (getId() == null && other.getId() == null) return uuid == other.uuid;
    return getId().longValue() == other.getId().longValue();
}

这样,实体可以安全地在集合中使用。当实体被分离时,它通过 ID 进行比较。当实体是瞬态的时,它会通过生成的 UUID 进行比较。所以我看到的唯一缺点是瞬态实体是通过 UUID 而不是业务密钥进行比较的。

非常欢迎任何建议!

4

1 回答 1

0

Liferay 执行类似于以下解决方案的操作。我希望它有所帮助。

此解决方案将需要您的表中的一个附加列和您的实体中的一个字段,该字段将包含一个唯一的“计数器”。这是使您的实体独一无二的计数器。

会有一个新表,比如“ENTITY_COUNTER”表,它有两列 - 1. 您的实体名称和 2. 给出的最高“可能”计数器。

您需要创建一个单例,以便在创建实体时将这些唯一计数器(认为令牌)分发给您的实体。每次实体获取令牌时,计数器都会增加 1。

您的单身人士不会每次都去数据库更新最高令牌。每次发出 1000 个唯一令牌时,它都会更新数据库。单例将获得一批 1000 个令牌来分发,一旦用完这些令牌,它将使用其持有的最高令牌编号更新 ENTITY_COUNTER 表。

例如,ENTITY_COUNTER 中的第一个更新将是 EntityName 1000,并且每次创建 1000 个实体时,该数字将增加 1000。

这样,您就可以拥有一个唯一标识符,该标识符在持久化之前可供您的实体使用。

于 2013-08-15T12:57:10.970 回答