Question

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=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;

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.

Was it helpful?

Solution 2

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.

OTHER TIPS

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 );
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top