2010-03-15 44 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的调用。