TLDR: переключены версии Hibernate с 3. на 5. . Теперь отношения OneToOne с общим первичным ключом, который отображается только в одном классе, сохраняют две сущности в неправильном порядке, нарушая ограничение внешнего ключа. Как изменить порядок?
В процессе миграции с экземпляра jboss 7 на текущий wildfly моей команде также пришлось обновить нашу версию hibernate с 3 до 5.3.10.
При этом я столкнулся с проблемой с одной из наших конструкций сущностей, в которой я столкнулся с кирпичной стеной.
Общая концепция такова:
У меня есть основной класс сущности в нем есть несколько «модулей» в качестве attritubes, которые совместно используют первичный ключ основного класса сущностей. Эти модули сами являются классами сущностей и содержат различные логики c и дальнейшие отношения. Однако у сущностей модуля нет никаких других постоянных атрибутов. Они также не содержат ссылки на основной класс сущностей.
В этом отношении это (в объектно-ориентированном мире java) однонаправленная связь с общим первичным ключом (я понимаю, что общий первичный ключ делает это двунаправленный для базы данных).
Код Java будет выглядеть примерно так:
@Entity(name = "mainEntity")
@Table(name = "main_entity")
public class MainEntity {
// Business Logic ...
@Id
private Long id;
@OneToOne( targetEntity = ModuleA.class, cascade = CascadeType.ALL, optional = false,
orphanRemoval = true )
@PrimaryKeyJoinColumn( name = "id", referencedColumnName = "id" )
private ModuleA moduleA;
// More Modules...
}
@Entity(name=moduleA)
@Table(name=module_a)
public class ModuleA {
@Id
private Long id;
// other relationships to entirely different entities,
// but no reference to mainEntity or other "modules"
}
В нашей предыдущей системе это работало просто отлично. При использовании чего-то вроде
entityManager.persist(mainEntity);
модули будут сохраняться сначала, а затем mainEntity.
Однако с нашей обновленной версией гибернации это не то, что происходит. Используя это отображение, порядок вставки меняется на противоположный, и entityManager сначала попытается сохранить mainEntity. Это приводит к нарушению ограничения внешнего ключа, которое должно предотвратить несоответствия между таблицами.
На заметку: я пытался изменить
@PrimaryKeyJoinColumn(...)
на
@MapsId(value="id")
Это фактически изменило порядок сохранения. Однако это привело к тому, что hibernate больше не правильно понимал общий первичный ключ -> Хотя сохранение по какой-то причине сработало,
entityManager.find(ModuleA.class,primaryKey);
не сработало, и таких ошибок, как «column mainEntity.moduleA_id, не существует. "
Есть ли способ, которым вы можете придумать express необходимость сохранения модулей в первую очередь, как это сделал Hibernate 3 для нас?
Я буду очень рад Спасибо за любую помощь.
PS: Это мой первый вопрос, если требуется дополнительная информация или если есть проблема с формулировкой, скажите, пожалуйста. :)