Vấn đề là với hashCode
của bạn triển khai trên Price
.
Việc triển khai cả hai equals
và hashCode
thường sai vì chúng chỉ dựa trên bình đẳng và tính toán băm dựa trên giá trị của ID
của thực thể chỉ còn. Trong các trường hợp mới được tạo mà ID
là một @GeneratedValue
kết quả là điều này sẽ không hoạt động.
Trong trường hợp của bạn, mỗi khi bạn thêm một Price
mới ví dụ cho Set<>
của bạn , cùng một hashCode
giá trị được tính toán vì mỗi phiên bản mới có ID
rỗng , vì vậy chúng tiếp tục được thay thế.
Điều chỉnh equals
của bạn và hashCode
triển khai:
@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();
}
Điều này đảm bảo rằng khi so sánh hai đối tượng không tồn tại của một Price
, so sánh / băm của chúng dựa trên các thuộc tính không phải danh tính. Sau khi được duy trì, các phương thức sẽ chỉ so sánh / băm dựa trên giá trị nhận dạng của chúng, cho phép hai trường hợp trong đó một cái đã được sửa đổi và cái kia không tương đương với cùng một giá trị.