3

我正在处理一个具有一些不寻常实体关系的项目,我在使用 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 似乎真的在这个操作中明确地试图对我不利。任何帮助,将不胜感激。

4

2 回答 2

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 );
}
于 2010-12-17T15:18:32.450 回答
0

使用 EntityManager.flush 方法解决,强制 JPA 首先持久化用户。

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

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

我仍然必须在用户的 activeX 列上允许空值,但这没关系,因为我至少可以在 X 上强制不为空。

于 2010-12-20T08:09:12.580 回答