2011-02-08 1 views
41

Я использую JPA 2.0 и спящий режим. У меня есть пользовательский класс и класс группы следующим образом:JPA Hibernate много-ко многим каскадом

public class User implements Serializable { 
    @Id 
    @Column(name="USER_ID") 
    private String userId; 

    @ManyToMany 
    @JoinTable(name = "USER_GROUP", 
       joinColumns = { 
        @JoinColumn(name = "GROUP_ID") 
       }, 
       inverseJoinColumns = { 
        @JoinColumn(name = "USER_ID") 
       } 
    ) 
    private Set<Group> groupList; 

    //get set methods 
} 

public class Group 
{ 
    @Id 
    @Column(name="GROUP_ID") 
    private String groupId; 

    @ManyToMany(mappedBy="groupList") 
    private Set<User> memberList; 
    //get set methods 
} 

А потом, я создаю пользователя и группу, а затем назначить пользователя в группу.

Что я хочу иметь, когда я удаляю группу, группа будет удалена (конечно), и все отношения группы пользователей, которые группа будет автоматически удаляться из таблицы соединений USER_GROUP, но сам пользователь будет не удаляется из таблицы USER.

С кодом, который у меня выше, только строка в таблице GROUP будет удалена при удалении группы, и пользователь все равно будет иметь запись в удаленной группе в таблице соединения USER_GROUP.

Если я ставлю каскад в классе пользователя, как это:

@ManyToMany(cascade=CascadeType.ALL) 
@JoinTable(name = "USER_GROUP", 
joinColumns = 
{ 
    @JoinColumn(name = "GROUP_ID") 
}, 
inverseJoinColumns = 
{ 
    @JoinColumn(name = "USER_ID") 
}) 
private Set<Group> groupList; 

При удалении группы, пользователь будет удален, как хорошо!

Есть ли способ достичь того, чего я хочу?

ответ

33

То, как вы его сопоставили, User является управляющей стороной отношений, поэтому он будет отвечать за обновление таблицы соединений.

Изменение JoinTable отображения из User в Group, и сделать groupList собственности User поэтому он имеет атрибут mappedBy. Это изменит группу на управляющую сторону отношений, а вызовы persist/update для группы будут управлять таблицей соединений.

Но учтите, что вы не сможете просто добавить группу к пользователю, сохранить пользователя и продолжить, вместо этого вам придется добавить пользователя в группу и сохранить группу, чтобы увидеть изменения, но с двунаправленным много-многим мы надеемся, что вы все равно будете управлять этими отношениями.

+0

Хммм, если я делаю то, что вы говорите (я не предполагаю никакого каскадирования вообще, так как вы ничего не упоминаете), когда у меня есть пользователь, назначенный определенной группе, что произойдет, когда я удалю пользователя? Удалятся ли отношения пользовательской группы в таблице соединений? Удалится ли сама группа? – Hery

+2

, если вы сделаете это так, как я сказал, отношения пользовательской группы будут полностью управляться групповой стороной вещей. Это означает, что вы, вероятно, вообще не сможете удалить пользователя, пока не удалите их из всех групп.Для этого вам нужно будет удалить пользователя из группы, а затем сохранить группу. При удалении только пользователь не удалит отношения пользовательской группы или таблицу соединений. Без каскада удаление группы удалит ассоциации, но не пользователи, и это то, что вы сказали, что хотите в исходном вопросе. – digitaljoel

+0

Я вижу ... Поэтому я должен использовать группу в качестве управляющей стороны ... Есть ли способ, чтобы обе стороны были управляющей группой? Другими словами, когда я удаляю пользователя, пользователь и группа пользователей также будут удалены, но не группа, и когда я удалю группу, группа и группа пользователей будут удалены, но не пользователь. – Hery

4

Как уже указывалось, сделайте владельца группы отношения, если вам не нужно каскадировать со стороны пользователя.

Затем попробуйте использовать cascade=CascadeType.MERGE, чтобы не удалять каскад пользователя при удалении группы.

5

Видя проблему под другим углом:

Вы можете добавить FK ограничения к вам многие-ко-многим таблицы отображения. На самом деле у вас всегда должны быть FK в вашем БД для целей целостности данных. Например, в этом случае, по крайней мере, пользователь не может быть удален при молчании оставления сиротских строк в таблице сопоставления.

Если у вас есть FK, вы можете указать на delete cascade referential action ограничениях, и БД будет управлять автоматическим удалением таблицы сопоставления, но не сущности, как вы просили.

 Смежные вопросы

  • Нет связанных вопросов^_^