views:

254

answers:

3

I have a @ManyToMany relationship between two entities. When I perform an update on the owning side, it appears that JPA deletes all the linked records from my database and re-inserts them. For me this is a problem because I have a MySQL trigger that fires before a record is deleted. Any ideas on how to get around this problem? Thanks RG

@Entity
public class User {

    @Id
    @Column(name="username")
    private String username;

    ...

    @ManyToMany
    @JoinTable(name="groups", joinColumns=
        @JoinColumn(name="username", referencedColumnName="username"),
            inverseJoinColumns=@JoinColumn(name="groupname",
                    referencedColumnName="type_id"))
    private List<UserType> types;

    ...

}

@Entity
public class UserType {

    @Id
    @Column(name="type_id")
    private String id;

    @ManyToMany(mappedBy="types")
    private List<User> users;

    ...
} 
+1  A: 

Its probably related to this question. You have to ensure you have an appropriately defined hashCode an equals method in your mapped object so that Eclipselink can determine equality and thus determine that the existing objects map to existing objects in the DB. Otherwise it has no choice but to recreate the child objects every time.

Alternatively, I've read that this kind of join can only support efficient adding and removing of list items if you use an index column, but that's going to be EclipseLink specific, since the JPA annotations don't seem to support such a thing. I know there is an equivalent Hibernate annotation, but I don't know what it would be in Eclipselink, if such a thing exists.

Jherico
Thanks for the insight. I tried overriding the equals and hashCode methods in my User class; however it still doesn't prevent JPA from removing/recreating the records in my join table. Perhaps I am not implementing this correctly...
reverendgreen
JPA doesn't use object identity but database identity.
Pascal Thivent
A: 

Try this one:

1) change declaration to:

private List<UserType> types = new Vector<UserType>();

2) never call

user.setTypes(newTypesList)

3) only call

user.getTypes().add(...);
user.getTypes().remove(...);
iimuhin
Could you please elaborate on why I should change my declaration?
reverendgreen
+1  A: 

It appears my problem was that I was not merging the entity.

reverendgreen