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.