Сложный JPA сохраняется
-
11-10-2019 - |
Вопрос
Я работаю над проектом с некоторыми необычными отношениями организации, которые у меня возникают проблемы с JPA. Есть два соответствующих объекта; Пользователь и давайте назовем другого X. У пользователя есть один-один-многие и два отношения один к одному с X. Это в основном выглядит так
Пользовательская сущность
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=true)
private List<X> xList;
@OneToOne
@JoinColumn(name = "active_x1_id")
private X activeX1;
@OneToOne
@JoinColumn(name = "active_x2_id")
private X activeX2;
X Entity
@ManyToOne()
@JoinColumn(name="user_id")
private User user;
Упорствуя нового пользователя, я также хочу сохранить две объекты X (одна для ActiveX1 и одно для ActiveX2) в одной транзакции. JPA обрабатывает это странно, журнал выглядит так:
INSERT INTO X VALUES (...) // x1
INSERT INTO USERS VALUES (...)
INSERT INTO X() VALUES (...) // x2
UPDATE USERS SET ...
UPDATE X VALUES (...) // updates x1
Это делает невозможным использовать не нулевые ограничения в базе данных. Есть ли лучший способ справиться с этими несколькими отношениями? Или способ контролировать, какой заказ JPA сохраняет объекты? JPA действительно, кажется, явно пытается работать против меня в этой операции. Любая помощь будет оценена.
Решение 2
Решено с использованием метода EntityManager.flush, заставив JPA сначала сохранить пользователя.
user.setProperties (свойства);
em.persist (пользователь);
em.flush ();
X x1 = новый x (пользователь);
user.setactivex1 (x1);
X x2 = new x (пользователь);
user.setactivex2 (x2);
Я все еще должен разрешать нулевые значения на колонке ActiveX пользователя, но это нормально, так как я могу, по крайней мере, не нулевой на X.
Другие советы
Почему бы вам просто не использовать аннотацию @notnull? Я не думаю, что есть способ изменить постоянный порядок. Вы должны сделать это вручную. Что-то вроде этого,
User user = ...;
if ( user.getActiveX1().getId() == null ) {
entityManager.persist( user.getActiveX1() );
} else {
entityManager.merge( user.getActiveX1() );
}
if ( user.getActiveX2().getId() == null ) {
entityManager.persist( user.getActiveX2() );
} else {
entityManager.merge( user.getActiveX2() );
}
if ( user.getId() == null ) {
entityManager.persist( user );
} else {
entityManager.merge( user );
}