問題はhashCode
にあります Price
での実装 。
両方のequals
の実装 およびhashCode
エンティティのID
の値のみに基づいて等価性とハッシュ計算を行うため、多くの場合間違っています。 それだけ。 ID
が新しく作成されたインスタンスの場合 @GeneratedValue
です 結果として、これは機能しません。
あなたの場合、新しいPrice
を追加するたびに Set<>
へのインスタンス 、同じhashCode
新しいインスタンスごとにnullのID
があるため、値が計算されます 、それで彼らは取り替えられ続けます。
equals
を調整します およびhashCode
実装:
@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();
}
これにより、Price
の2つの非永続オブジェクトを比較するときに確実になります 、それらの比較/ハッシュは非同一性属性に基づいています。永続化されると、メソッドはID値のみに対して比較/ハッシュを基にし、一方が変更され、もう一方が同じと等しくない2つのインスタンスを可能にします。