2009-08-19 1 views
5

У меня есть 2 объекта: User и UsersList.Hibernate @ManyToMany удалить отношение

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

и

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

и код как этот: стол

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

На стадии 1 У меня 3 строки в ПОЛЬЗОВАТЕЛЕЙ (USER_ID) ,

После шага 2 (второй комментарий) у меня есть 1 строка в таблице USERS_LIST (USERS_LIST_ID) и в таблицу соединений USERS_LIST_USERS (USER_ID, USERS_LIST_ID) 3 строки.

То, что я хочу достичь на шаге 3, заключается в следующем: когда я удаляю одного пользователя из таблицы USERS - допустим, пользователь с USER_ID = 4, я хочу, чтобы только строка с USER_ID = 4 из таблицы соединений была удалена , а остальные останутся.

Есть ли аннотация для решения моей проблемы?

+0

Как выглядит метод deleteWithHibernate? –

ответ

-1

Я думаю, вы должны, как это annotaion

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

и изменение cascade.remove к CascadeType.ALL ваш код должен быть что-то вроде этого

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

@OnDelete - это аннотация спящего режима и недоступна в JPA. – Mohsen

9

Что вам нужно, это @JoinTable атрибут :

Hibernate не знает, что отношения «многие ко многим» относятся друг к другу и, вероятно, создают две таблицы соединений. Если вы укажете тот же @JoinTable по обе стороны отношения, он будет работать так, как ожидалось.

Убедитесь, что joinColumn и inverseJoinColumn являются противоположностями на противоположных сторонах отношения.

  • joinColumn на одной стороне == inverseJoinColumn на другой стороне
  • inverseJoinColumn на одной стороне == joinColumn на другой стороне

Я надеюсь, что это помогает.

@Entity 
public class Role extends Identifiable { 

    @ManyToMany(cascade ={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) 
    @JoinTable(name="Role_Permission", 
      [email protected](name="Role_id"), 
      [email protected](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", 
      [email protected](name="Permission_id"), 
      [email protected](name="Role_id") 
     ) 
    public List<Role> getRoles() { 
     return roles; 
    } 

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

} 
+1

Я использую '@JoinTable' в своем решении, но по-прежнему не могу удалить строки. Нужно ли упоминать все упомянутые вами каскады? – Logan

+1

OP использует 'mappedBy', недостаточно ли для спящего режима знать, что должно выглядеть' @ JoinTable'? Явное перечисление имени и столбцов '@ JoinTable' кажется немного лишним, если вы действительно не хотите, чтобы ваши точные имена использовались. – fommil

+0

Отличное решение! – kinkajou