我知道这个话题已经讨论了很多次,但仍然需要对我们面临的问题作一些澄清。 Hibernate best practices谈论使用自然键进行equals / hashCode方法。我们有一个复合键,它由一个特定对象所属的2个参数(比如String name,Organization org)组成。不幸的是我不能使用org,因为它是懒惰加载并导致其他问题,我也不想创建代理键(可能是从数据库自动生成的,也可能是在创建对象之前通过API调用创建的UUID)。我真正拥有什么样的选项,因为在上面的Object(name,org)字段中是唯一的,我不能只根据名称字段本身编写我的逻辑。代理键是唯一的选项,这是否意味着我必须将此值存储为表中每行的一部分?
答案 0 :(得分:4)
如果你想要像
那样的话public class MyEntity {
private String name;
private Organization organization;
// getter's and setter's
public boolean equals(Object o) {
if(!(o instanceof MyEntity))
return false;
MyEntity other = (MyEntity) o;
return new EqualsBuilder().append(getName(), other.getName())
.append(getOrganization(), other.getOrganization())
.isEquals();
}
}
但是如果你想避免它,因为你现在想要加载一个延迟加载的实体,你可以依靠Hibernate.isInitialized方法并提供你的自定义例程
public boolean equals(Object o) {
if(!(o instanceof MyEntity))
return false;
MyEntity other = (MyEntity) o;
boolean equals = new EqualsBuilder().append(getName(), other.getName())
.isEquals();
if(Hibernate.isInitialized(getOrganization())) {
// loaded Organization
} else {
// supply custom routine
}
return equals;
}
我有一个未更新的网页,其中Hibernate提供以下矩阵
no eq/hC at all eq/hC with the id property eq/hC with buisness key
use in a composite-id No Yes Yes
multiple new instances in set Yes No Yes
equal to same object from other session No Yes Yes
collections intact after saving Yes No Yes
其中各种问题如下:
在复合ID中使用:
要将对象用作复合id,它必须以某种方式实现equals / hashCode,在这种情况下== identity将不够。
集合中的多个新实例:
以下是否有效:
HashSet someSet = new HashSet();
someSet.add(new PersistentClass());
someSet.add(new PersistentClass());
assert(someSet.size() == 2);
等于来自其他会话的同一对象:
以下是否有效:
PersistentClass p1 = sessionOne.load(PersistentClass.class, new Integer(1));
PersistentClass p2 = sessionTwo.load(PersistentClass.class, new Integer(1));
assert(p1.equals(p2));
保存后收藏完整:
以下是否有效:
HashSet set = new HashSet();
User u = new User();
set.add(u);
session.save(u);
assert(set.contains(u));
它还强调了这个Thread,其中讨论了equals / hashCode实现
答案 1 :(得分:2)
Hibernate最佳实践谈论使用equals / hashCode方法的自然键。
是的,所以我不会详细说明。
我们有一个复合键,它由一个特定对象所属的2个参数(比如String name,Organization org)组成。不幸的是,我不能使用org,因为它是懒惰加载并导致其他问题。
你能详细说一下,也许用一些代码说明一下吗?我想了解你是如何准确地完成这项工作的,以及问题是什么。
我真正拥有什么样的选项,因为在上面的Object(name,org)字段中是唯一的,我不能只根据名称字段本身编写逻辑。
正如我所说,提供更多细节可能有所帮助。但为了以防万一,请注意,只要您使用property access type,在代理上调用org.getId()
就不应该触发实体的加载,因此您应该能够在等于实现中使用它
答案 2 :(得分:0)
什么是被称为具有名称和组织的对象?我猜它叫做Foo。我认为你不能说foo.getOrganization()因为数据库连接已关闭?您是否可以更改您的FooDAO,以便在从数据库中读取foo后立即加载组织?
然后,当您需要使用equals()和hashCode()时,它将可用。