use*_*188 22 java persistence entitymanager
如果我有多个线程,每个使用注入器来获取EntityManager对象,每个使用em对象来选择其他类对象的列表.准备用于for循环.
如果一个线程首先完成并调用clear(),那会影响其他线程吗?喜欢for循环会有异常吗?
close()怎么样?
如果答案是"它取决于",那么(类定义?方法调用?)和where(java code?annotation?xml?)应该看看它是如何依赖的?
我没有写源,我只是在没有文档的情况下使用其他人的库.
谢谢.
Mak*_*kky 28
这是完整的工作thread-safe Entity Manager Helper.
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class EntityManagerHelper {
private static final EntityManagerFactory emf;
private static final ThreadLocal<EntityManager> threadLocal;
static {
emf = Persistence.createEntityManagerFactory("Persistent_Name");
threadLocal = new ThreadLocal<EntityManager>();
}
public static EntityManager getEntityManager() {
EntityManager em = threadLocal.get();
if (em == null) {
em = emf.createEntityManager();
// set your flush mode here
threadLocal.set(em);
}
return em;
}
public static void closeEntityManager() {
EntityManager em = threadLocal.get();
if (em != null) {
em.close();
threadLocal.set(null);
}
}
public static void closeEntityManagerFactory() {
emf.close();
}
public static void beginTransaction() {
getEntityManager().getTransaction().begin();
}
public static void rollback() {
getEntityManager().getTransaction().rollback();
}
public static void commit() {
getEntityManager().getTransaction().commit();
}
}
Run Code Online (Sandbox Code Playgroud)
pru*_*nge 12
实体管理器不是线程安全的(源Java EE 6教程),并且不能在线程之间共享.每个线程都需要使用自己的实体管理器,否则会发生不好的事情,无论是调用clear()还是close()调用.
但是,如果注入器使用自己的实体管理器注入每个线程,那么事情应该没问题.
Spring和可能的其他DI框架会将真实实体管理器的基于ThreadLocal的代理注入到bean中.每个线程所做的调用将代理实体管理器的真实线程本地实例 - 这就是事情可以工作的方式,即使它可能看起来实体管理器在多个线程之间共享.
有关如何注入实体管理器的更多细节将有所帮助(Spring等)
管理 EntityManager 有两种类型:容器管理和应用程序管理。对于应用程序管理,获取EntityManager的首选方法是通过EntityManagerFactory。Java EE 教程是这样说的:
\n\n\n\n\n容器管理的实体管理器
\n\n使用容器管理的实体管理器,EntityManager 实例\xe2\x80\x99s 持久性上下文会由容器自动传播到在单个 Java\n 事务 API (JTA) 中使用 EntityManager 实例的所有应用程序组件\n ) 交易。
\n\nJTA 事务通常涉及跨应用程序组件的调用。\n 要完成 JTA 事务,这些组件通常需要访问\n单个持久性上下文。当通过 javax.persistence.PersistenceContext 注释将 EntityManager 注入到应用程序组件时,就会发生这种情况。持久性上下文会随当前 JTA 事务自动传播,并且映射到同一持久性单元的 EntityManager 引用提供对该事务内持久性上下文的访问。通过自动传播持久性上下文,应用程序组件不需要将 EntityManager 实例的引用相互传递,以便在单个事务中进行更改。Java EE 容器管理容器管理的实体管理器的生命周期。
\n\n要获取 EntityManager 实例,请将实体管理器注入\n 应用程序组件:
\n\nRun Code Online (Sandbox Code Playgroud)\n\n@PersistenceContext \nEntityManager em; \n应用程序管理的实体管理器
\n\n另一方面,对于应用程序管理的实体管理器,持久性上下文不会传播到应用程序组件,并且 EntityManager 实例的生命周期由应用程序管理。
\n\n当应用程序需要访问不使用 JTA 事务在特定持久性单元中跨 EntityManager 实例传播的持久性上下文时,将使用应用程序管理的实体管理器。在这种情况下,每个 EntityManager 都会创建一个新的、隔离的持久性上下文。EntityManager 及其关联的持久性上下文由应用程序显式创建和销毁。当无法直接注入 EntityManager 实例时,也会使用它们,因为 EntityManager 实例不是线程安全的。EntityManagerFactory 实例是线程安全的。
\n
http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html
\n