Hibernate Удалить каскад - PullRequest
       24

Hibernate Удалить каскад

9 голосов
/ 14 октября 2008

У меня есть одна сущность [Проект], которая содержит коллекцию других сущностей [Вопросы].

Я сопоставил отношение с помощью каскадного атрибута "all-delete-orphan".

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

Когда я выполняю session.delete (project), он выдает исключение, говорящее, что project_id не может быть нулевым, но если я удаляю ограничение not-null для этого поля, удаление работает хорошо.

Кто-нибудь знает, как это решить?

Ответы [ 3 ]

11 голосов
/ 14 октября 2008

Прямо из документации . Это объясняет вашу проблему именно так, как я считаю:

Однако этот код

Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;

p.Children.Remove(c);
c.Parent = null;
session.Flush();

не удалит c из базы данных; он только удалит ссылку на p (и в этом случае вызовет нарушение ограничения NOT NULL). Вам нужно явно удалить () ребенка.

Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;

p.Children.Remove(c);
session.Delete(c);
session.Flush();

Теперь, в нашем случае, Ребенок не может существовать без своего родителя. Поэтому, если мы удаляем Child из коллекции, мы действительно хотим, чтобы он был удален. Для этого мы должны использовать cascade = "all-delete-orphan".

<set name="Children" inverse="true" cascade="all-delete-orphan">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>

Редактировать:

Что касается обратного, я полагаю, что это определяет только то, как генерируется sql, для получения дополнительной информации см. doc .

Стоит отметить, у вас есть

not-null="true"

в отношении многие-к-одному в вашей конфигурации hibernate?

0 голосов
/ 14 октября 2008

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

0 голосов
/ 14 октября 2008

Удаление происходит сначала в Проекте и каскадно к Вопросу, но удаление Проекта включает нулевой идентификатор_проекта в Вопросах (для ссылочной целостности. Вы не получаете исключение при удалении объекта Вопрос, но потому что каскад пытается обнулить ФК в вопросе (ах).

Глядя на « Сохранение Java с Hibernate », я думаю, что вам действительно нужен каскадный тип удаления или удаления, а не удаления-сироты.

...