我正在使用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”并更新值的对象,这些更改会自动持久保存到db,即使没有事务并且我没有明确地“manager.save(state)”对象?我问,因为它似乎是,我想知道冲洗是否正在这样做?
答案 0 :(得分:1)
根据FlushMode
的javadoc(我假设这是一个JPA 1.0问题),正如@Konrad所指出的那样:
如果没有活动的事务,则持久性提供程序不得刷新到数据库。
由于您很有可能使用transaction-type="RESOURCE_LOCAL"
作为持久性广告单元,因为我看不到begin
/ commit
围绕您对EntityManager
的调用(对于我而言,没有任何交易活跃,所以我不希望任何事情被冲洗。
无论如何,正如好JPA Concepts页面中提醒的那样:
- 使用
<persistence-unit transaction-type="RESOURCE_LOCAL">
你负责EntityManager
(PersistenceContext / Cache)创建 并跟踪......
- 您必须使用 得到一个EntityManagerFactory 的EntityManager
- 结果
EntityManager
实例是一个 PersistenceContext /缓存- 一种
EntityManagerFactory
可以通过注入 仅@PersistenceUnit
注释(不是@PersistenceContext)- 你是 不允许使用@PersistenceContext来引用单位 类型RESOURCE_LOCAL
- 您 必须使用
EntityTransaction
API围绕您的每次通话开始/提交 EntityManger- 呼叫
entityManagerFactory.createEntityManager()
两次导致两次分开 EntityManager实例及其原因 两个单独的PersistenceContexts / Caches。- 是的 几乎从不一个好主意,拥有多个实例 正在使用的EntityManager(不要创建 第二个,除非你已经摧毁了 第一)
所以,在我看来,你应该修复你的代码,如果你的代码不正确,就没有真正想知道意外行为。只需在交易中执行对EntityManager
的调用。
答案 1 :(得分:0)
你怎么知道没有交易?你在EJB中使用它吗?在那种情况下,我打赌有交易。
来自文档(http://java.sun.com/javaee/6/docs/api/javax/persistence/FlushModeType.html):
如果设置了FlushModeType.COMMIT,则 更新对实体的影响 查询的持久化上下文 没有具体说明。
如果没有活动的交易,则 持久性提供程序不得刷新 数据库。
如果您在交易中,附加的实体(即在同一交易中加载的实体)会自动记录到数据库中。