Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

java - What is the correct way of overriding hashCode () and equals () methods of persistent entity?

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...