• Remove Associations on @ManyToMany Delete

    Posted on May 15, 2012 by in Dev Note, Java, Spring Roo

    Here’s a quick note summarizing my investigation on JPA @ManyToMany…

    When you have a @ManyToMany one side will be the side that “ownes” the relationship and the other side does not. This means which side of the Many-To-Many will be in charge of updating the join table on the add or remove of the relationship.

    Here are my simplified test Entities.

    public class MyUser {
        @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
        private Set<Auth> roles = new HashSet<Auth>();
    }
    public class Auth {
        @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
        private Set<MyUser> users = new HashSet<MyUser>();
    }

    So when you remove the “owner” Entity MyUser it will remove the row in the relationship table that relates to Auth. But I was having a hard time figuring out the best way to get the relationships to MyUser instances severed (not deleted) when my code removes the “not owning” Entity MyAuth.

    The way to do it is removing the relationship manually with a @PreRemove JPA lifecycle callback annotation on the Auth Class.

        @PreRemove
        @SuppressWarnings("unused")
        private void removeUsers() {
        	for (MyUser user: users) {
        		user.getRoles().remove(this);
        	}
        }

    This will get called right before the Auth object is removed and clear out the MyUser references to this Auth object.

    Is there a better way to do this?

2 Responsesso far.

  1. Ben S. says:

    Oh, additionally to seamlessly add User’s from the Auth Entities (that doesn’t own the relationship) you use the @PrePersist annotation.

    @PrePersist
    private void addusers() {
    	for (MyUser user: users) {
    		user.getRoles().add(this);
    	}
    }
    
  2. Damian says:

    VERY useful! thanks!!