Complex JPA persist order issue
I'm working on a project with some unusual entity relations which i'm having problems persisting with JPA. There are two relevant objects; User and let's call the other X. User has a one-to-many AND two one-to-one relations to X. It basicly looks like this
[User entity]
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=tru开发者_StackOverflow社区e)
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;
When persisting a new user, I also want to persist two x entities (one for activeX1 and one for activeX2) in a single transaction. Jpa handles this abit weird, the log looks like this:
INSERT INTO X VALUES (...) // x1
INSERT INTO USERS VALUES (...)
INSERT INTO X() VALUES (...) // x2
UPDATE USERS SET ...
UPDATE X VALUES (...) // updates x1
This makes it impossible to use NOT NULL constraints in the database. Is there any better way to handle these multiple relationships? Or a way to control which order JPA persists objects? JPA really seems to explicitly try to work against me in this operation. Any help would be appreciated.
Why don't you just use @NotNull annotation? I don't think there is a way to change persist order. You have to do it manually. Something like this,
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 );
}
Solved with the use of EntityManager.flush method, forcing JPA to persist the user first.
user.setProperties(properties);
em.persist(user);
em.flush();
X x1 = new X(user);
user.setActiveX1(x1);
X x2 = new X(user);
user.setActiveX2(x2);
I still have to allow null values on the activeX-column of user, but that is alright as I can at least force not null on X.
精彩评论