0

I am working on an web application running on GlassFish 4.1.1, using EclipseLink 2.6.1. I have a unidirectional ManyToMany relationship between Users and Projects, and when I remove elements from User.projects and merge the User, the join rows are not removed in the database. I made a smaller demo app to isolate it:

User class:

@Entity
@Table(name = "demouser")
public class DemoUser implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DemoUserSeq")
    @SequenceGenerator(name = "DemoUserSeq", sequenceName = "demouser_userid_seq", allocationSize = 1)
    @Column(name = "userid")
    private Integer id;
    @Column(name = "username")
    private String userName;
    // some more fields
    @JoinTable(name = "demouserprojbind", joinColumns = {
        @JoinColumn(name = "username", referencedColumnName = "username")
    }, inverseJoinColumns = {
        @JoinColumn(name = "projcode", referencedColumnName = "projcode")
    })
    @ManyToMany
    private Set<DemoProject> projects;

DemProject does NOT have a mapped ManyToMany to Users. The binding table "demouserprojbind" binds with unique (not-null) text columns instead of the serial PKs.

Demo update code:

DemoUser user = getUser(username); // EntityManager Query by username
Set<DemoProject> userProjects = user.getProjects();
userProjects.clear();
EntityManager em = emf.createEntityManager();
utx.begin();
em.joinTransaction();
em.merge(user);
em.flush();
utx.commit();
em.close();

This is demo code made in a Servlet - emf and utx and injected EntityManagerFactory and UserTransaction.

When I trace the SQL from EclipseLink, it looks like this:

DELETE FROM demouserprojbind WHERE ((projcode = ?) AND (username = ?))
bind => [Project2, null]
DELETE FROM demouserprojbind WHERE ((projcode = ?) AND (username = ?))
bind => [Project1, null]

It is apparently unable to put in the username of the owning entity - the SQL matches no rows, and thus no rows are deleted from the database.

Is there anything I do wrong in my save logic (I want to delete the binding between a User and a Project, but both the User and Project themselves should remain), or is it a bug in EcliseLink?

thomjah
  • 43
  • 5
  • 1
    Is this the only thing that isn't working, and do you have any customizations on the mapping, or events on the entity? JPA does not allow using non-pk fields in relationships, and while it is supported by most providers (EclipseLink allows it) it does cause issues with things like caching and usually results in warnings. Verify that some event isn't being triggered to set the userName=null, or that you haven't modified a read-only instance somehow such that a query for that user name gives back a corrupted entity from the cache. – Chris Dec 02 '15 at 15:29

1 Answers1

0

In your

@ManyToMany
private Set<DemoProject> projects;

Put in the anotation ManyToMany the cascade type, like this:

@ManyToMany(cascade={CascadeType.MERGE, CascadeType.REMOVE })
private Set<DemoProject> projects;
Dazak
  • 1,011
  • 2
  • 9
  • 17
  • My demo code actually had "(cascade = CascadeType.ALL)", and setting to (cascade={CascadeType.MERGE, CascadeType.REMOVE }) did not improve the situation. – thomjah Dec 16 '15 at 09:50