views:

2614

answers:

2

Hello.

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 ??

Thanks.

A: 

I think you must as this annotaion

    @OnDelete(action = OnDeleteAction.CASCADE)
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

and change cascade.remove to CascadeType.ALL your code must be something like this

   @ManyToMany(cascade = CascadeType.ALL, mappedBy = "users")
   @OnDelete(action = OnDeleteAction.CASCADE)
   @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private List<UsersList> usersLists = new ArrayList<UsersList>();
Am1rr3zA
+1  A: 

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;
    }

}
andersjanmyr