| I am using the following Customer entity with an @Embeddable Address:
@Entity
public class Customer {
@Id @GeneratedValue
private Integer id;
private Address address;
public Customer() {
this.address = Address.DEFAULT;
}
public Address getAddress() { return this.address; }
}
@Embeddable
public class Address {
public static final Address DEFAULT = new Address("london");
private String city;
public String getCity() { return city; }
}
Note that Customer sets its reference to the Address to a static constant default value in its default constructor. The problem is that merging a customer object changes the default Address like this:
entityManager.merge(new Customer(new Address("paris")));
assertEquals("london", Address.DEFAULT.getCity());
As a consequence if I merge two transient customers with different addresses within the same transaction they end up having the same addresses when the transaction commits and the address of the customer that is merged first is written to the database with a false value:
Customer mrsParis = entityManager.merge(new Customer(new Address("paris")));
Customer mrBerlin = entityManager.merge(new Customer(new Address("berlin")));
assertEquals( "paris", mrsParis.getAddress().getCity() );
This problem does not occur in EclipseLink. |