Подтвердить что ты не робот

JPA Hibernate много-ко-многим каскадным

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

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.

Если я помещаю каскад в класс User следующим образом:

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

Когда я удалю группу, пользователь также будет удален!

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Увидев проблему под другим углом:

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

Когда у вас есть FK, вы можете указать удалить каскадное ссылочное действие по ограничениям, а БД будет управлять автоматическим удалением таблицу отображения, но не объекта, как вы просили.

Ответ 3

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

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

Ответ 4

Вы можете сделать что-то вроде этого

@PreRemove
private void removeMembers() {
    this.memberList.clear();
}