Сложные JPA сохраняют проблему заказа - PullRequest
3 голосов
/ 17 декабря 2010

Я работаю над проектом с некоторыми необычными отношениями сущностей, которые у меня не решаются с 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 сущность]

@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  

Это делает невозможным использование ограничений NOT NULL в базе данных. Есть ли лучший способ справиться с этими множественными отношениями? Или способ контролировать, в каком порядке JPA сохраняет объекты? JPA действительно, кажется, явно пытается работать против меня в этой операции. Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2010

Решено с использованием метода EntityManager.flush, заставляющего JPA сначала сохранить пользователя.

user.setProperties (properties);
em.persist (user);
em.flush();

X x1 = новый X (пользователь);
user.setActiveX1 (x1);
X x2 = новый X (пользователь);
user.setActiveX2 (x2);

Мне все еще нужно разрешить нулевые значения в столбце activeX пользователя, но это нормально, так как я могу, по крайней мере, принудительно установить значение NULL в X.

0 голосов
/ 17 декабря 2010

Почему бы вам просто не использовать аннотацию @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 );
}
...