2010-09-24 47 views
3

我知道这个话题已经被讨论了很多次,但仍然需要对我们正面临的问题作一些澄清。休眠最好practices谈论使用自然键的equals/hashCode方法。我们确实有一个组合键,它由2个参数组成(称为String name,Organization org),一个特定对象所属的参数。不幸的是,我不能使用org,因为它被延迟加载并导致其他问题,我也不想创建代理键(可能是从数据库自动生成的,或者是在创建对象之前通过API调用创建的UUID)。因为在上面的Object(name,org)字段中是独一无二的,我不能只根据name字段本身来写我的逻辑。代理键是唯一的选择,这是否意味着我必须将此值作为表中每行的一部分存储?使用自然键作为equals和hashCode的一部分

回答

2

Hibernate最佳实践讨论使用equals/hashCode方法的自然键。

是的,我不会详细说明这一点。

我们确实有一个组合键,它由2个参数组成(称为String name,Organization org),特定对象所属的组合键。不幸的是,我不能使用org,因为它被延迟加载并导致其他问题。

你能详细说明一下,也许用一些代码说明吗?我想了解你是如何准确地完成这项工作的,以及问题所在。

在上面的Object(name,org)字段中,我确实拥有什么样的选项是唯一的,我不能仅仅基于name字段本身来编写我的逻辑。

正如我所说,提供更多的细节可能会有所帮助。但为了以防万一,请注意,在代理上调用org.getId()不应触发加载实体,只要您使用的是property access type,那么您应该能够在等式实现中使用它。

+0

最多访问策略,它允许用户获得关联实体的标识符而不会触及数据库 – 2010-09-25 02:33:43

0

什么是对象有一个名称和组织?我会假设它叫做Foo。我认为你不能说foo.getOrganization(),因为数据库连接已关闭?你能否改变你的FooDAO,以便在从数据库读取foo时立即加载组织?

然后,当你需要用equals()和hashCode()做些什么的时候它就可以使用了。

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; 
} 

我有没有更新的网页,休眠提供以下矩阵

         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在某些情况下,在这种情况下,==身份是不够的。在集

多个新的实例:

请问以下工作与否:

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哪里等于/的hashCode实现大量用于指定属性讨论

+0

恕我直言,问题在于hashCode的实现离子。我想知道OP如何用他懒惰的组织来实现(一致的)hashCode。 – 2010-09-25 12:34:00

相关问题