Най-доброто изпълнение на equals
и hashCode
е, когато използвате уникален бизнес ключ или естествен идентификатор, като този:
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true, updatable = false)
private String name;
@Override
public int hashCode() {
HashCodeBuilder hcb = new HashCodeBuilder();
hcb.append(name);
return hcb.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Company)) {
return false;
}
Company that = (Company) obj;
EqualsBuilder eb = new EqualsBuilder();
eb.append(name, that.name);
return eb.isEquals();
}
}
Бизнес ключът трябва да е последователен при всички преходи на състояние на обект (преходно, прикачено, отделено, премахнато), ето защо не можете да разчитате на id за равенство.
Друг вариант е да преминете към използване на UUID идентификатори, зададени от логиката на приложението. По този начин можете да използвате UUID за equals
/hashCode
, защото идентификаторът се присвоява преди обектът да бъде изчистен.
Можете дори да използвате идентификатора на обекта за equals
и hashCode
, но това изисква винаги да връщате една и съща стойност [hashCode
, така че да сте сигурни, че стойността на hashCode на обекта е последователна във всички преходи на състоянието на обекта, като това:
@Entity(name = "Post")
@Table(name = "post")
public class Post implements Identifiable<Long> {
@Id
@GeneratedValue
private Long id;
private String title;
public Post() {}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Post))
return false;
Post other = (Post) o;
return id != null &&
id.equals(other.getId());
}
@Override
public int hashCode() {
return getClass().hashCode();
}
//Getters and setters omitted for brevity
}
person
Vlad Mihalcea
schedule
27.06.2014