2010-12-17 85 views
3

我正在與一些不尋常的實體關係的項目工作,我遇到了JPA持續存在的問題。有兩個相關的對象;用戶並讓我們把其他X用戶有一個一對多和兩個一到一個關係到X.它basicly看起來像這樣複雜的JPA持續訂單問題

[User實體]

@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確實似乎明確地試圖對付我。任何幫助,將不勝感激。

+0

不是null你是什麼意思「JPA處理這個問題有點怪」?您正在使用JPA的特定實現... Hibernate?的EclipseLink?它是*執行*正在做你說的。這並不意味着所有的JPA實現都會這樣做 – DataNucleus 2010-12-17 18:46:30

+0

你是對的,我的意思是EclipseLink。 – 2010-12-20 07:51:33

回答

0

使用EntityManager.flush方法解決,迫使JPA先堅持用戶。

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

X x1 = new X(user);
user.setActiveX1(x1);
X x2 = new X(user);
user.setActiveX2(x2);

我還是要允許對用戶的activex列空值,但這是正常的,因爲我至少可以力X上

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); 
} 
+0

根據我的經驗,@NotNull僅在自動創建數據庫時僅從符號創建,而在運行時不會生效。無論如何,我設法使用EntityManager的flush方法來解決它,請參閱下面的細節。 – 2010-12-20 08:10:50