Problemet är med din hashCode
implementering på Price
.
Implementeringar av båda equals
och hashCode
ofta fel eftersom de baserar sin likhet och hashberäkning enbart på värdet av enhetens ID
endast. I fall av nyskapade instanser där ID
är en @GeneratedValue
resultatet kommer detta inte att fungera.
I ditt fall, varje gång du lägger till ett nytt Price
instans till din Set<>
, samma hashCode
värdet beräknas eftersom varje ny instans har ett ID
null , så de byts ut hela tiden.
Justera dina equals
och hashCode
implementeringar:
@Override
public boolean equals(Object object) {
if ( object == this ) {
return true; // instance equality
}
if ( object == null || object.getClass() != getClass() ) {
return false;
}
final Price other = Price.class.cast( object );
if ( getId() == null && other.getId() == null ) {
// perform equality check against all non-id attributes
}
else {
// perform equality check only on id
}
}
@Override
public int hashCode() {
final HashCodeBuilder hcb = new HashCodeBuilder( 17, 37 );
if ( id == null ) {
hcb.append( price );
hcb.append( discount );
// other fields
}
else {
// only identity basis
hcb.append( id );
}
return hcb.toHashCode();
}
Detta säkerställer att när man jämför två icke-beständiga objekt av ett Price
, deras jämförelse/hash baseras på icke-identitetsattributen. När metoderna har bestått baserar de sin jämförelse/hash endast mot identitetsvärdet, vilket tillåter två fall där den ena har modifierats och den andra inte behöver motsvara detsamma.