2014-01-08 130 views
0

Hibernate EntityManager如何在多线程应用程序中使用(例如,每个客户端连接在服务器上启动它自己的线程)。多线程应用程序中的EntityManager?

EntityManager的是否应仅仅通过EntityManagerFactory的创建一次,如:

private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit"); 
private static EntityManager em = emf.createEntityManager(); 
    public static EntityManager get() { 
     return em; 
    } 

还是我必须重新为每个线程的entitymanger,并为每个关闭EM交易?

我的CRUD方法看起来就像这样:

public void save(T entity) { 
    em.getTransaction().begin(); 
    em.persist(entity); 
    em.getTransaction().commit(); 
    em.close(); 
} 

public void delete(T entity) { 
    em.getTransaction().begin(); 
    em.remove(entity); 
    em.getTransaction().commit(); 
    em.close(); 
} 

我会havew运行emf.createEntityManager()每个.begin()过吗?还是我陷入困境,因为每个人都在用自己的缓存创建一个自己的EntityManager实例?

+0

所以用这个,很明显,我将有一个单一的EMF,并为每个线程创建一个新的EM。但仍然:如果我在每次交易后关闭EM,我是否每次都需要重新创建EM(在线程中多次)? – membersound

+0

关闭EM后,您无法再使用它了。但你当然可以使用一个EM进行多次交易。请记住,EM是一个为廉价创作而设计的轻量级对象。确定你的工作单位并为他们使用一个EM。你可能会发现[参考文档](http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/)有趣。 –

回答

2

5.1. Entity manager and transaction scopes

一个EntityManager是应该被使用一次,对于一个单一 业务流程一种廉价的,非线程对象,工作的单个单元,然后丢弃。

这完全回答你的问题。不要通过线程共享EM。只要这些交易是工作单位的一部分,就使用一个EM进行多次交易。

而且你已经closed后,您不能使用EntityManger它:

close方法被调用后,从获得的EntityManager实例的所有方法和任何查询,TypedQuery和StoredProcedureQuery对象它会抛出IllegalStateException。

考虑这样的事情:

public class Controller { 

    private EntityManagerFactory emf; 

    public void doSomeUnitOfWork(int id) { 
     EntityManager em = emf.createEntityManager(); 
     em.getTransaction().begin(); 

     CrudDao dao = new CrudDao(em); 

     Entity entity = dao.get(id); 
     entity.setName("James"); 
     dao.save(entity); 

     em.getTransaction.commit(); 
     em.close(); 
    } 

} 
+0

是的,因为EM不是线程安全的,如果我在它的周围创建一个包装,并在内部调用EM的保存/更新的包装中包含'synchronized'保存/更新方法,它是否可以跨多个线程使用。我也永远不清除/关闭EM?我认为仍然存在同时读写的问题。您能否让我知道您对此的评论? – bluelurker

+0

为什么你想添加这样的复杂性,而EM创建成本低?我只能想象,如果你的线程与工作单元所处的环境相同,这是有道理的。 –

+0

是为每个线程创建单独的EM绝对是最好的选择。我只是好奇,如果我上面说的是足够安全的。你能否在“相同的背景”部分上谈一谈。对不起,我没有明白。 – bluelurker