#hibernate #foreign-keys #hibernate-cascade
#гибернация #внешние ключи #гибернация-каскад
Вопрос:
У меня есть следующая настройка
A -> B -> C
A-сопоставление:
<hibernate-mapping>
<class name="db.base.A" table="A">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<set name="Bs" table="BI18n" inverse="true" lazy="true" fetch="select" cascade="all-delete-orphan">
<key>
<column name="A_id" not-null="true" />
</key>
<one-to-many class="db.base.B" />
</set>
</class>
</hibernate-mapping>
B:
<hibernate-mapping>
<class name="db.base.B" table="B">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="A" class="db.base.A" fetch="select">
<column name="A_id" not-null="true" />
</many-to-one>
<set name="B" table="B" inverse="true" lazy="true" fetch="select" cascade="all-delete-orphan">
<key>
<column name="id" not-null="true" />
</key>
<one-to-many class="db.base.BI18n" />
</set>
</class>
</hibernate-mapping>
Substanceitentified 18n:
<hibernate-mapping>
<class name="db.base.BI18n" table="B18n">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="B" class="db.base.B" fetch="select">
<column name="id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Когда я вставляю новый A с полным графом объектов через
HibernateDaoSupport.merge(AObj);
все создано правильно.
Но если я использую
HibernateDaoSupport.saveOrUpdate(AObj);
Я получаю DataIntegrityException
Cannot add or update a child row: a foreign key constraint fails
(`table`.`B18n`, CONSTRAINT `B18n_fk`
FOREIGN KEY (`id`) REFERENCES `B` (`id`))
Когда я смотрю в журнал log4j, я вижу, что с merge
- он вставляет
B
- он вставляет
B18n
С saveOrUpdate
его помощью
- вставки
B18n
, которые, очевидно, приводят к исключению
это определенное (ожидаемое) поведение или что-то не так с моей настройкой.
Комментарии:
1. Вы уверены, что каждая ассоциация инициализирована правильно, в обоих направлениях (т.Е. Если захват имеет substanceIdentified, то этот substanceIdentified должен указывать на захват, и наоборот)?
2. да, это на самом деле сгенерировано Джексоном. Я передаю Джексону данные JSON, и он генерирует для меня весь объектный граф.
Ответ №1:
После некоторой возни a выяснил, каким было решение.
Я добавлял новые элементы к существующим B
. Но не установил идентификатор B
, потому что слияние выполняет a SELECT
из графа объектов до того, как он выполнит сохранение / обновление, это не проблема.
saveOrUpdate
с другой стороны, это не так. Поэтому исключение.
Дело закрыто 😉