重写持久化实体的hashCode()和equals()方法的正确方法是什么? [英] What is the correct way of overriding hashCode () and equals () methods of persistent entity?

查看:137
本文介绍了重写持久化实体的hashCode()和equals()方法的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的类角色:

  @Entity 
@Table(name =ROLE)
public class Role实现Serializable {

@Id
@GeneratedValue
private Integer id;
@Column
private String roleName;

public Role(){}
$ b $ public Role(String roleName){
this.roleName = roleName;
}

public void setId(Integer id){
this.id = id;
}

public Integer getId(){
return id;
}

public void setRoleName(String roleName){
this.roleName = roleName;
}

public String getRoleName(){
return roleName;




$ b现在我想覆盖它的方法equals和hashCode。我的第一个建议是:

  public boolean equals(Object obj){
if(obj instanceof Role){
return((Role)obj).getRoleName().equals(roleName);
}
返回false;
}

public int hashCode(){
return id;
}

但是当我创建新的Role对象时,它的id为null。这就是为什么我有一些hashCode方法实现的问题。现在我可以直接返回 roleName.hashCode()但是如果roleName不是必需的字段?我几乎可以肯定,编写更复杂的例子并不难,它通过返回其中一个字段的hashCode无法解决。

因此,我希望看到一些相关讨论的链接或听取您解决此问题的经验。感谢!

解决方案

Bauer和King的书使用Hibernate的Java持久化建议不要使用等于关键字的字段和hashCode。他们建议你应该选择什么是对象的业务关键字段(如果没有人工关键字)并使用它们来测试相等性。因此,在这种情况下,如果角色名称不是必需的字段,您可以找到必要的字段并将它们组合使用。在代码中,您发布了角色名称,除了id外,您还可以使用角色名称。



以下是第398页的报价:
$ b


我们认为,实质上每个实体类都应该有一些商业密钥,即使它包含类(这将适用于一些不可变类)。业务密钥是用户唯一识别特定记录的东西,而代理键是应用程序和数据库使用的。

业务密钥相等表示equals()方法仅比较构成业务密钥的属性。这是一个完美的解决方案,可以避免前面提到的所有问题。唯一的缺点是需要额外考虑才能确定正确的业务关键。无论如何,这一努力是必需的。如果您的数据库必须通过约束检查确保数据完整性,那么识别任何唯一的键是很重要的。


我用一个简单的方法构建一个equals hashcode方法是创建一个toString方法,该方法返回'business key'字段的值,然后在equals()和hashCode()方法中使用它。澄清:当我不关心性能(例如,在rinky-dink内部webapps中)时,这是一种懒惰的方法,如果预期性能会成为问题,那么您自己编写方法或使用IDE的代码生成工具。

I have a simple class Role:

@Entity
@Table (name = "ROLE")
public class Role implements Serializable {

    @Id
    @GeneratedValue
    private Integer id;
    @Column
    private String roleName;

    public Role () { }

    public Role (String roleName) {
        this.roleName = roleName;
    }

    public void setId (Integer id) {
        this.id = id;
    }

    public Integer getId () {
        return id;
    }

    public void setRoleName (String roleName) {
        this.roleName = roleName;
    }

    public String getRoleName () {
        return roleName;
    }
}

Now I want to override its methods equals and hashCode. My first suggestion is:

public boolean equals (Object obj) {
    if (obj instanceof Role) {
        return ((Role)obj).getRoleName ().equals (roleName);
    }
    return false;
}

public int hashCode () {
    return id; 
}

But when I create new Role object, its id is null. That's why I have some problem with hashCode method implementation. Now I can simply return roleName.hashCode () but what if roleName is not necessary field? I'm almost sure that it's not so difficult to make up more complicated example which can't be solved by returning hashCode of one of its fields.

So I'd like to see some links to related discussions or to hear your experience of solving this problem. Thanks!

解决方案

Bauer and King's book Java Persistence with Hibernate advises against using the key field for equals and hashCode. They advise you should pick out what would be the object's business key fields (if there was no artificial key) and use those to test equality. So in this case if role name was not a necessary field you would find the fields that were necessary and use them in combination. In the case of the code you post where rolename is all you have besides the id, rolename would be what I'd go with.

Here's a quote from page 398:

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 things 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 presented 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.

An easy way I use to construct an equals and hashcode method is to create a toString method that returns the values of the 'business key' fields, then use that in the equals() and hashCode() methods. CLARIFICATION: This is a lazy approach for when I am not concerned about performance (for instance, in rinky-dink internal webapps), if performance is expected to be an issue then write the methods yourself or use your IDE's code generation facilities.

这篇关于重写持久化实体的hashCode()和equals()方法的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆