O problema é com seu
hashCode
implementação em Price
. Implementações de ambos
equals
e hashCode
muitas vezes errado porque eles baseiam sua igualdade e cálculo de hash apenas no valor do ID
da entidade só. Em casos de instâncias recém-criadas em que o ID
é um @GeneratedValue
resultado, isso não vai funcionar. No seu caso, sempre que você adicionar um novo
Price
instância para seu Set<>
, o mesmo hashCode
valor é calculado porque cada nova instância tem um ID
nulo , então eles continuam sendo substituídos. Ajuste seu
equals
e hashCode
implementações:@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();
}
Isso garante que ao comparar dois objetos não persistentes de um
Price
, sua comparação/hash é baseada nos atributos de não identidade. Uma vez persistidos, os métodos basearão sua comparação/hash apenas no valor de identidade, permitindo duas instâncias em que uma foi modificada e a outra não deve ser igualada.