Embeddable Must Implement equals() and hashCode()
ID |
java.hibernate_equals_in_embeddable |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
best-practice, hibernate, orm, reliability |
Description
Reports @Embeddable classes that do not declare both equals(Object) and hashCode(). Hibernate relies on value equality to detect changes to embedded components during dirty-checking. Without these methods, modifications to embedded objects may go undetected and never be persisted.
Rationale
Embedded components (value objects) are mapped as part of the owning entity’s table. Hibernate compares the previous state with the current state using equals() to decide whether an UPDATE statement is needed. When equals() and hashCode() are missing, Object.equals() (identity comparison) is used instead, and Hibernate may either miss real changes or issue spurious updates.
// Bad: @Embeddable without equals/hashCode
@Embeddable
public class Address {
private String street;
private String city;
private String zipCode;
}
Remediation
Implement both equals(Object) and hashCode() in every @Embeddable class, comparing all persistent fields that define the component’s value identity.
// Good: @Embeddable with proper equals/hashCode
@Embeddable
public class Address {
private String street;
private String city;
private String zipCode;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Address)) return false;
Address that = (Address) o;
return Objects.equals(street, that.street)
&& Objects.equals(city, that.city)
&& Objects.equals(zipCode, that.zipCode);
}
@Override
public int hashCode() {
return Objects.hash(street, city, zipCode);
}
}