Hibernate @ManyToMany delete relation

annotations, hibernate, many-to-many

Solution

What you need is the @JoinTable attribute:

Hibernate does not know that the many-to-many relations refer to each other and will probably create two join tables. If you specify the same @JoinTable on both sides of the relation it will work as expected.

Make sure that the joinColumn and the inverseJoinColumn are opposites on the opposing sides of the relation.

- joinColumn on one side == inverseJoinColumn on other side

- inverseJoinColumn on one side == joinColumn on other side

I hope this helps.

@Entity
public class Role extends Identifiable {

    @ManyToMany(cascade ={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name="Role_Permission",
            joinColumns=@JoinColumn(name="Role_id"),
            inverseJoinColumns=@JoinColumn(name="Permission_id")
        )
    public List<Permission> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<Permission> permissions) {
        this.permissions = permissions;
    }
}

@Entity
public class Permission extends Identifiable {

    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name="Role_Permission",
            joinColumns=@JoinColumn(name="Permission_id"),
            inverseJoinColumns=@JoinColumn(name="Role_id")
        )
    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

}

Problem

I have 2 entities: User and UsersList. ``` @Entity @Table(name = "USERS") public class User { @Id @GeneratedValue @Column(name = "ID") private Long id; @ManyToMany(cascade = CascadeType.REMOVE, mappedBy = "users") private List<UsersList> usersLists = new ArrayList<UsersList>(); public List<UsersList> getUsersLists() { return usersLists; } public void setUsersLists(List<UsersList> usersLists) { this.usersLists = usersLists; } } ``` and ``` @Entity @Table(name = "USERS_LIST") public class UsersList { @Id @GeneratedValue @Column(name = "ID") private Long id; @ManyToMany private List<User> users = new ArrayList<User>(); public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } } ``` and code like this one: ``` // 1 List<User> dbUsers; // 3 the user instances are persisted in DB UsersList usersList = new UsersList(); usersList.setUsers(dbUsers); // 2 - now persist the usersList using hibernate... saveWithHibernate(usersList); //3 - delete using a persisted user deleteWithHibernate(dbUsers.get(0).getId()); ``` where ``` deleteWithHibernate(Long id) { User usr = hibernateTemplate.get(User.class, id); hibernateTemplate.delete(usr); } ``` In step 1 I have 3 rows in the USERS (USER_ID) table. After step 2 (second comment) I have 1 row in the USERS_LIST (USERS_LIST_ID) table and into the join table USERS_LIST_USERS (USER_ID, USERS_LIST_ID) 3 rows. What I want to achieve in step 3 is the following: when I delete one user from the table USERS - let's say user with USER_ID = 4, I want just the row with USER_ID = 4 from the join table to be deleted, and the others to remain. Is there an annotation solution to my problem?

Original source