2010-03-15 43 views
1

我使用JPA和讓說我做這樣的事情JPA,範圍和自動保存?

public class MoRun extends Thread {... 
public void run() { 
    final EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("pu"); 
    EntityManager manager = emFactory.createEntityManager(); 
    manager.setFlushMode(FlushModeType.COMMIT); 
    someMethod(manager); 
    ... 
} 


public void someMethod(EntityManager manager){ 
    Query query = manager.createNamedQuery("byStates"); 
    List<State> list = query.getResultList(); 
    for (State state : list) { 
     if(someTest) 
      state.setValue(...) 
    } 
... 
} 

因此,對於那些通過「someTest」對象和值被更新的那些變化自動保存到數據庫,即使沒有交易,我不要明確「manager.save(狀態)」的對象?我問,因爲它似乎是這樣,我想知道是否沖水是這樣做的?

+0

你在哪裏運行這段代碼?你使用什麼'transaction-type'(RESOURCE_LOCAL或TRANSACTION)? – 2010-03-15 20:55:29

回答

0

你怎麼知道沒有交易?你使用EJB嗎?在這種情況下,我敢打賭有一筆交易。

從文檔(http://java.sun.com/javaee/6/docs/api/javax/persistence/FlushModeType.html):

如果FlushModeType.COMMIT被設置, 效果更新後的查詢 在 持久化上下文的實體作出是不確定的。

如果沒有事務處於活動狀態,則 持久性提供程序不得將數據庫刷新到 。

如果您處於事務中,則附加實體(即在同一事務中加載的實體)將自動記錄到數據庫中。

+0

我正在創建entitymanager(就在我調用上述方法之前,我做了這個EntityManager manager = emFactory.createEntityManager(););我自己,所以我知道沒有其他事務。 – arinte 2010-03-15 20:47:10

1

FlushMode javadoc的(我假設這是一個JPA 1.0的問題),並且指出了@Konrad:

如果沒有活動的事務,持久性提供一定不能沖水到數據庫。

既然你很可能使用你的持久單元transaction-type="RESOURCE_LOCAL",因爲我沒有看到任何begin/commit您的通話周圍您EntityManager(這是不好的,更多的只是在此之後),用於我沒有交易活躍,所以我不希望任何東西被刷新。

無論如何,提醒在漂亮的JPA Concepts頁:

  • 隨着<persistence-unit transaction-type="RESOURCE_LOCAL"> 負責EntityManager (PersistenceContext /緩存)創建 和跟蹤...
    • 必須使用 EntityManagerFactory的獲得一個 的EntityManager
    • 產生的 EntityManager實例是 PersistenceContext /緩存
    • EntityManagerFactory可以通過 @PersistenceUnit註解注入只有(不是@PersistenceContext)
    • 您是 允許使用@PersistenceContext指單位類型RESOURCE_LOCAL的
    • 必須使用EntityTransaction API到每一個電話開始/提交同意你 EntityManger
    • 調用 entityManagerFactory.createEntityManager() 兩次結果在兩個單獨 EntityManager實例及其因此 兩個單獨的PersistenceContexts/Caches。
    • 這是 幾乎從未一個好主意(除非你破壞了 先不要創建 第二個)在使用中有一個 的EntityManager的多個實例

所以,在我看來,你應該修復你的代碼在這裏,有在想意想不到的行爲沒有真正的問題,如果你的代碼不正確。只需在交易中執行對您的EntityManager的調用。