El problema está en tu hashCode
implementación en Price
.
Implementaciones de ambos equals
y hashCode
a menudo se equivocan porque basan su igualdad y cálculo de hash únicamente en el valor del ID
de la entidad solamente. En casos de instancias recién creadas donde el ID
es un @GeneratedValue
resultado, esto no funcionará.
En tu caso, cada vez que agregas un nuevo Price
instancia a su Set<>
, el mismo hashCode
el valor se calcula porque cada nueva instancia tiene un ID
nulo , por lo que siguen siendo reemplazados.
Ajusta tus equals
y hashCode
implementaciones:
@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();
}
Esto asegura que al comparar dos objetos no persistentes de un Price
, su comparación/hash se basa en los atributos que no son de identidad. Una vez persistentes, los métodos basarán su comparación/hash solo en el valor de identidad, lo que permite dos casos en los que uno se modificó y el otro no tiene que equivaler a lo mismo.