Hibernate @ManyToMany supprimer la relation

j'ai 2 entités: User et 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;
    }
}

et

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

et code comme celui-ci:

// 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());

deleteWithHibernate(Long id) {
        User usr = hibernateTemplate.get(User.class, id);
        hibernateTemplate.delete(usr);
}

à l'étape 1, j'ai 3 lignes dans la table USERS (USER_ID).

après l'étape 2 (deuxième commentaire) j'ai 1 ligne dans la table USERS_LIST (USERS_LIST_ID) et dans la table join USERS_LIST_USERS (USER_ID, USERS_LIST_ID) 3 lignes.

ce que je veux accomplir à l'étape 3 est le suivant: lorsque je supprime un utilisateur de la table USERS - disons user with USER_ID = 4, je veux juste la ligne avec USER_ID = 4 de la table jointure à supprimer, et les autres à rester.

y a-t-il une solution annotée à mon problème?

5
demandé sur Brian Tompsett - 汤莱恩 2009-08-19 15:54:21

2 réponses

ce dont vous avez besoin est l'attribut @JoinTable:

Hibernate ne sait pas que les relations de plusieurs à plusieurs se réfèrent l'un à l'autre et vont probablement créer deux tables de jointure. Si vous spécifiez la même @JoinTable des deux côtés de la relation, cela fonctionnera comme prévu.

assurez-vous que la colonne de jonction et la colonne inverse sont opposés sur l'opposé les côtés de la relation.

  • joinColumn sur un côté == inverseJoinColumn de l'autre côté
  • colonne inversée d'un côté == colonne de jonction de l'autre côté

j'espère que cela vous aidera.

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

}
9
répondu andersjanmyr 2009-09-17 12:06:16

je pense qu'il faut que ce annotaion

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

et changez cascade.supprimer pour CascadeType.TOUT votre code doit être quelque chose comme ça

   @ManyToMany(cascade = CascadeType.ALL, mappedBy = "users")
   @OnDelete(action = OnDeleteAction.CASCADE)
   @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private List<UsersList> usersLists = new ArrayList<UsersList>();
-1
répondu Am1rr3zA 2009-08-20 10:19:06