Как правильно настроить каскад гибернации

#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

  1. он вставляет B
  2. он вставляет B18n

С saveOrUpdate его помощью

  1. вставки B18n , которые, очевидно, приводят к исключению

это определенное (ожидаемое) поведение или что-то не так с моей настройкой.

Комментарии:

1. Вы уверены, что каждая ассоциация инициализирована правильно, в обоих направлениях (т.Е. Если захват имеет substanceIdentified, то этот substanceIdentified должен указывать на захват, и наоборот)?

2. да, это на самом деле сгенерировано Джексоном. Я передаю Джексону данные JSON, и он генерирует для меня весь объектный граф.

Ответ №1:

После некоторой возни a выяснил, каким было решение.

Я добавлял новые элементы к существующим B . Но не установил идентификатор B , потому что слияние выполняет a SELECT из графа объектов до того, как он выполнит сохранение / обновление, это не проблема.

saveOrUpdate с другой стороны, это не так. Поэтому исключение.

Дело закрыто 😉