2008-11-12 161 views
3

我一直在JBoss上使用hibernate/JPA幾個月了,有一個問題,我找不到答案或解決方案。堅持使用休眠/ JPA

這似乎創造新的實體bean時,就像我不能做一個查詢之前,我至少有人稱EntityManager.persist(EntityBean的),否則我得到以下錯誤:

TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

一個例子:

Job job = new Job(); 
Collection<Task> tasks = job.getTasks(); 
//entityManager.persist(job); 
ActionPlan actionPlan = (ActionPlan) entityManager.createNamedQuery("ActionPlan.findByCommand"). 
       setParameter("type", RunOperation.Install).getSingleResult(); 
Task task = Task.getTask(actionPlan); 
task.setActionPlan(actionPlan); 
tasks.add(task); 
task.setJob(job); 

我的問題是,我不能叫createNamedQuery不首先堅持「工作」(被註釋掉行)。 ActionPlan與Job有關係,但NamedQuery(findByCommand)不加入Job。困擾我的是,爲了查詢數據庫,當新創建的Job在這種情況下甚至沒有興趣時,我需要堅持Job。
將調用persist()移至片段的末尾會產生上述錯誤。

我知道我正在處理的對象不是持久的,但持續使得如果發生錯誤時不可能回滾。

我相信有一個解決方案,所以如果有人有答案,我會非常感激。我錯過了什麼?

回答

3

看起來合乎邏輯,你不能查詢不在數據庫中的東西,不是嗎?你可以做的是開始使用交易。在一個簡單的例子中,你的會話將有一個交易將被打開,直到你關閉會話。此時交易將被提交,並且所有更改都將持續。所有你需要的是在錯誤的情況下回滾你的交易。

P.S. Here at the bottom你可以找到「一個典型的交易應該使用以下成語」。

Session sess = factory.openSession(); 
Transaction tx; 
try { 
tx = sess.beginTransaction(); 
    //do some work 
    ... 
    tx.commit(); 
} 
catch (Exception e) { 
    if (tx!=null) tx.rollback(); 
    throw e; 
} 
finally { 
    sess.close(); 
} 
+0

不幸的是上面的鏈接被打破。 – kipz 2010-12-24 23:01:02

+0

修復了鏈接並添加了代碼,以防萬一。 – 2010-12-27 19:18:11

0

我知道,我不能查詢什麼還沒有被堅持 - 這是不是這種情況。我想找到的是其他實體bean。不只是相同的類型,而是我擁有的任何類型的實體bean。然後我得到TransientObjectException。

我提到過我使用JBoss嗎?我相信使用J2EE和JPA服務器控制我的事務,最後我想幹的是干涉它?所以對我來說,除了使用requiresNew等,我不會惹事務 - 服務器。

也許我應該移動hibernate標籤,因爲實際上我使用的是JPA - JBoss使用hibernate。所以請在任何代碼示例中涉及這一點。

0

即使你堅持對象,你仍然可以回滾它。只有在EntityManager上調用flush之後纔會同步到底層數據庫。

0

嗯,我認爲Java EE 5 Tutorial中的答案和閱讀內容給了我正確的答案。

與我的看法相反,persist()不是而是刷新到數據庫,它只是將實體bean移動到持久狀態。欺騙我的是,我注意到,在調用persist之後,實體實際上會持久保存到數據庫(也可能是錯誤消息中的'save'字)。我把它當做flush來叫做結束我的事務,但是如果我正確地使用了malkolm,我仍然可以自己或通過服務器回滾異常。

所以我得出的結論是;只要有一個新的實體出現,只要它與另一個實體不存在關係,就應該調用堅持。
然後交易得以維持,服務器更喜歡你;)

她留下的是我仍然不明白爲什麼我不能在沒有一切處於持久狀態的情況下進行查詢。