Как убедиться, что Hibernate 5 сохраняется в правильном порядке в отношениях один-к-одному с общим первичным ключом - PullRequest
1 голос
/ 06 февраля 2020

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: Это мой первый вопрос, если требуется дополнительная информация или если есть проблема с формулировкой, скажите, пожалуйста. :)

1 Ответ

0 голосов
/ 06 марта 2020

Хорошо, после некоторого Анализа я хотел бы поделиться тем, что мы сделали по этому поводу.

Во-первых, приведенное в вопросе отображение работает для Hibernate 3.6.10. это начинает терпеть неудачу. Как ни странно, начиная с 5.4.0.CR1 он снова начинает работать.

Мы не нашли способа продолжать использовать это отображение с установленным ограничением. В нашем случае мы решили, что ограничение просто не стоит хлопот, но для более надежного отображения такого рода вещей мы обнаружили, что работа с @MapsId была более успешной. Там для модулей потребуется ссылка на MainEntity, и они будут использовать @MapsId для получения своего идентификатора.

...