实体等于(),hashCode()和toString().如何正确实施它们?

spi*_*e07 32 java orm entity hibernate

我执行equals(),hashCode()toString()通过在Bean所有可用字段我的实体.

当我尝试比较相等或者打印obj状态时,我在前端得到了一些Lazy init Exception.那是因为实体中的某些列表可以延迟初始化.

我想知道实现equals()toString()实体对象的正确方法是什么.

Boz*_*zho 17

equals()并且hashCode()应该使用业务键实现 - 即一组唯一标识对象但不是其自动生成的ID的属性.

toString()你可以把任何有趣的信息 - 例如所有领域.

使用您的IDE(Eclipse,NetBeans,IntelliJ)为您生成所有这些.

为了避免LazyInitializationException,无论是在equals()视图中还是在视图中(jsp),都可以使用OpenSessionInView.


sim*_*mon 10

当您为Hibernate对象实现equals和hashCode方法时,重要的是

  1. 使用getter而不是直接访问类属性.
  2. 不能直接比较对象的类,但使用instanceof替代

更多信息:

Stackoverflow:overriding-equals-and-hashcode-in-java

Hibernate文档:Equals和HashCode

编辑:关于不访问类属性的相同规则也直接应用于toString方法 - 仅使用getters保证返回实际包含在类中的信息.


Art*_*ald 7

  1. 如果两个对象相等,则它们必须具有相同的哈希码.
  2. 默认情况下,equals()方法检查两个引用是否引用Java堆上的相同内存中实例

可以依靠实体标识符来使用equals来比较您的实体

public boolean equals(Object o) {
    if(o == null)
        return false;

   Account account = (Account) o;
   if(!(getId().equals(account.getId())))
       return false;

   return true;
}
Run Code Online (Sandbox Code Playgroud)

但是当你有一个非持久的实体时会发生什么.它不起作用,因为尚未分配其标识符.

那么让我们看看Java Persistence with Hibernate Book对它的讨论

业务键是属性或属性的某种组合,对于具有相同数据库标识的每个实例都是唯一的.

所以

如果您没有使用代理主键,那么它将是您使用的自然键.

因此,假设您有一个用户实体,其自然键是firstName和lastName(至少,他/她的firstName和lastName通常不会更改).所以它将被实现为

public boolean equals(Object o) {
    if(o == null)
        return false;

    if(!(o instanceof User))
        return false;

    // Our natural key has not been filled
    // So we must return false;
    if(getFirstName() == null && getLastName() == null)
        return false;

    User user = (User) o;
    if(!(getFirstName().equals(user.getFirstName())))
        return false;

    if(!(getLastName().equals(user.getLastName())))
        return false;

   return true;
}

// default implementation provided by NetBeans
public int hashcode() {
    int hash = 3;

    hash = 47 * hash + ((getFirstName() != null) ? getFirstName().hashcode() : 0)
    hash = 47 * hash + ((getLastName() != null) ? getLastName().hashcode() : 0)

    retrun hash;
}
Run Code Online (Sandbox Code Playgroud)

它工作正常!我甚至使用Mock对象,如存储库,服务等

关于toString()方法,正如@Bozho所说,你可以把任何有趣的信息.但是请记住一些Web框架,例如Wicket和Vaadin,使用此方法来显示其值.