Как НЕ каскадировать удаление в рекурсивном отношении?

У меня есть объект, который имеет отношения ManyToMany с самим собой:

@Entity
public class User {

    @Id
    private Long id;

    @ManyToMany
    private List<User> friends;
}

Как я могу удалить пользователя, не удаляя всех его друзей? Очевидно, я не могу использовать каскадное удаление. Если я попытаюсь удалить пользователя без каскадирования, я получу эту ошибку: «Невозможно удалить или обновить родительскую строку: ограничение внешнего ключа не работает»


person Yashima    schedule 25.11.2011    source источник


Ответы (3)


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

How can I delete a user without deleting all of his friends? Приведенный ниже вариант является одним из них.

Учитывая ваше специальное сопоставление, List<User> в User, вы должны только обновлять ссылки на таблицы сопоставления и ничего не удалять из таблицы User, потому что у них могут быть другие User в друзьях, и это может создать проблемы.

person ManuPK    schedule 25.11.2011
comment
звучит здорово, как мне это сделать, не прибегая к нативным запросам? - person Yashima; 25.11.2011
comment
как насчет HQL? Я не уверен, что это можно сделать с помощью каких-либо опций в отображении. - person ManuPK; 25.11.2011
comment
HQL лишь минимально лучше нативных запросов. Но, думаю, мне придется прибегнуть к этому. Что касается социальных сетей в наши дни, эта проблема должна возникать чаще. Но тогда кракены социальных данных не любят удалять данные после их сбора, я думаю - person Yashima; 25.11.2011
comment
Есть вещи, которые вы должны делать с HQL, и именно по этой причине. Проголосуйте за / примите ответы, если они полезны. - person ManuPK; 30.11.2011

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

Вот почему у вас есть нарушение ограничения, если вы не каскадируете, потому что ссылка (U1, U2), которая имеет ограничения внешнего ключа для обоих пользователей, все еще существует, пока вы пытаетесь удалить одного из 2 пользователей.

person Sebastien Lorber    schedule 25.11.2011
comment
@ManyToMany(cascade=CascadeType.REMOVE) -> это удаляет отношение и пользователей, я только что проверил это еще раз. - person Yashima; 25.11.2011
comment
нет проблем, все равно спасибо за попытку помочь. Может оказаться (см. ниже), что я не могу использовать аннотации, чтобы исправить это - person Yashima; 25.11.2011

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

person Dominik    schedule 24.11.2012