Masalahnya ada pada hashCode
Anda implementasi pada Price
.
Implementasi dari keduanya equals
dan hashCode
sering salah karena mereka mendasarkan kesetaraan dan perhitungan hash hanya dari nilai ID
entitas hanya. Dalam kasus instance yang baru dibuat di mana ID
adalah @GeneratedValue
hasilnya, ini tidak akan berhasil.
Dalam kasus Anda, setiap kali Anda menambahkan Price
baru instance ke Set<>
. Anda , hashCode
yang sama nilai dihitung karena setiap instance baru memiliki ID
null , jadi mereka terus diganti.
Sesuaikan equals
dan hashCode
implementasi:
@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();
}
Ini memastikan bahwa ketika membandingkan dua objek yang tidak bertahan dari Price
, perbandingan/hash mereka didasarkan pada atribut non-identitas. Setelah bertahan, metode akan mendasarkan perbandingan/hashnya hanya terhadap nilai identitas, memungkinkan dua contoh di mana satu telah dimodifikasi dan yang lainnya tidak sama.