Hi,
I am running into a somewhat strange issue; I have the following JPA mapping:
Code:
@Entity
public class Location {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "LOCATION_ID")
private Long id;
@OneToMany( cascade = { CascadeType.ALL }, fetch = FetchType.EAGER )
@JoinTable( joinColumns = { @JoinColumn( name = "LOCATION_ID" ) },
inverseJoinColumns = { @JoinColumn( name = "ATTRIBUTE_ID" ) } )
private Set<Attribute> attributes;
and:
Code:
@Entity
public class Attribute implements IAttributeSupport {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ATTRIBUTE_ID")
private Long id;
@Column(nullable = false) private String name;
@Column(nullable = false) private String value;
...
And I'm doing a simple test:
- persist a Location with a few Attributes
- change the name of one of these Attributes
- merge the Location back (with the changed Attribute)
My expectation (considering the propagation) is that
merging the Location would simply propagate to the Attributes, which would get updated. This happens (broadly) - the value of the Attribute that was changed is indeed updated, but then a new INSERT is attempted in the Join Table, where the mapping already exist. Because of this new and unnecessary insert, the failure (as expected) is:
Quote:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key 'PRIMARY'
Now, the culprit seems to be the way hashCode and equals are implemneted - it seems that, when the set of attributes gets persisted by Hibernate, the collection persister check if each entry (each Attribute) needs to be inserted:
Quote:
if ( collection.needsInserting( entry, i, elementType ) )
So, since the name of one of the attributes did change, now this is picked up as needing to be inserted (which is not really correct - inserting is not needed, only update is) - hence the insert operation in the Join Table. I could of course use the id for equals and hashcode, but that's not the way Hibernate recommends it, and also I would rather not do that. Am I missing something in the mapping that may lead to this? This is a pretty standard mapping - simple one to many and simple merge operation - any suggestions to make it work?
Any help is appreciated.
Thanks.
Eugen.