Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » ManyToMany bidirectional deletion
ManyToMany bidirectional deletion [message #640753] Tue, 23 November 2010 01:56 Go to next message
Brendan Haverlock is currently offline Brendan HaverlockFriend
Messages: 46
Registered: July 2009
Member
Hi guys,

I have a relatively straight-forward problem. I have two classes: user and security role. Users have security roles and security roles have users.

In the User class I have the following:

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
    @JoinTable(name = "person_security_role",
                joinColumns = {@JoinColumn(name = "person_key")},
                inverseJoinColumns = {@JoinColumn(name = "security_role_key")})
    private List<SecurityRole> securityRoles;


In the SecurityRole class I have the following:

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}, mappedBy = "securityRoles")
    private List<User> users;


Now when I run the following test code I get two lists with different sizes:

        User user = new User();

        SecurityRole securityRole = new SecurityRole();
        user.addSecurityRole(securityRole);

        user = sb.updateFlush(user);

        securityRole = user.getSecurityRoles().get(0);
        user.getSecurityRoles().remove(0);

        user = sb.updateFlush(user);

        int userSecurityRolesSize = user.getSecurityRoles().size();
        int securityRoleUsersSize = em.find(SecurityRole.class, securityRole.getSecurityRoleKey()).getUsers().size();


The list of users on the SecurityRole object has a size of 1, and the list of securityRoles on the user has the size of 0.

How do I make it so Eclipselink goes out and deletes the orphan from the list on the other side of the relationship without having to go over there and delete it myself?

Thanks!
Re: ManyToMany bidirectional deletion [message #640920 is a reply to message #640753] Tue, 23 November 2010 14:45 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1039
Registered: July 2009
Senior Member
Hello,

EclipseLink has bidirectional relationship maintanence as a hold over from EJB2.0 support, but it is strongly not recommended. You can set it through a customizer using the ForeignReferenceMapping's setRelationshipPartnerAttributeName method on both relationship mappings to indicate to each what the other side is. As mentioned though, this is not recommended, as it causes unexpected results later on - once the control is given to the relationship, it cannot be turned off when required.
It is recommended instead that helper methods be used on entities that set backpointers for users where required - such as adding addSecurityRole/removeSecurityRole methods to User that would also set SecurityRole's User at the same time.

Best Regards,
Chris
Re: ManyToMany bidirectional deletion [message #640983 is a reply to message #640920] Tue, 23 November 2010 18:12 Go to previous messageGo to next message
Brendan Haverlock is currently offline Brendan HaverlockFriend
Messages: 46
Registered: July 2009
Member
I was afraid you would say that. Unfortunately, I don't have time to add the remove methods to every entity with a many to many. This used to work fine until I enabled the secondary shared cache. It makes sense why it worked with the cache turned off because it was always fetching from the db and when I deleted one side, it would delete from the many to many joiner and then when I fetched the other side, there was no row in the joining table so the counts were correct. I guess I could write some code that walks the object graph pre-persistence and does the remove for me, but EclipseLink should be doing this for me! Wink Is this handled by default in JPA 2.0?
Re: ManyToMany bidirectional deletion [message #641290 is a reply to message #640983] Wed, 24 November 2010 18:44 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1039
Registered: July 2009
Senior Member
Hello,

No, it is not available in JPA - it was included in the now defunct EJB 2.0, but I believe not included in the JPA/EJB3.0 spec, as they seemed to try to make Entities as close to pojos as possible - avoiding the weight of EJBs from EJB 2.0. In my opinion, et wasn't a very great aspect of EJB 2.0 and its inflexibility added more headaches than it was worth.

Be aware that your object model traversal might come at a performance cost unless you are careful not to trigger lazy relationships unless there was a change on one side.

Best Regards,
Chris
Re: ManyToMany bidirectional deletion [message #641294 is a reply to message #641290] Wed, 24 November 2010 18:54 Go to previous message
Brendan Haverlock is currently offline Brendan HaverlockFriend
Messages: 46
Registered: July 2009
Member
I know this all too well as I have done this in the past. I had to add an annotation for relationships that should not be loaded when the object graph was being traversed. It may be more of a PITA to do this again than to just add the remove methods. Thanks for the help, though, everything works great with the cache off. I am going to stick with it off until I have time to revisit this defect and do it the proper way. Appreciate the help!
Previous Topic:EclipseLink/Examples/JPA/RCP
Next Topic:MySQL: update on self-referencing foreign key tables leads to Duplicate Key Exception
Goto Forum:
  


Current Time: Thu Dec 18 11:41:07 GMT 2014

Powered by FUDForum. Page generated in 0.01856 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software