复杂的JPA持续订单问题

时间:2010-12-17 13:52:12

标签: jpa entity-relationship persist

我正在开展一个项目,其中包含一些不寻常的实体关系,我在持续使用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处理这个abit很奇怪,日志看起来像这样:

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 :(得分:0)

为什么不使用@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 );
}

答案 1 :(得分:0)

使用EntityManager.flush方法解决,迫使JPA首先保留用户。

user.setProperties(属性);
em.persist(用户);
em.flush();

X x1 =新X(用户);
user.setActiveX1(X1);
X x2 = new X(用户);
user.setActiveX2(X2);

我仍然需要在用户的activeX-column上允许空值,但这没关系,因为我至少可以在X上强制不为null。