Java 为给定的PersistenceContext注入了多少EntityManager?

Java 为给定的PersistenceContext注入了多少EntityManager?,java,jpa,ejb-3.0,Java,Jpa,Ejb 3.0,我正在无状态的EJB3bean中注入EntityManager对象(充当DAO对象,每个对象提供对不同数据库表的访问)。部署在JBoss AS 7中 然后,我使用EJB3bean方法中的System.identityHashCode添加了代码,以查看EntityManager注入的各种实例(希望在所有DAO中看到相同的实例)。例如: @Stateless public class AFacade { @PersistenceContext(unitName="foo") Enti

我正在无状态的EJB3bean中注入EntityManager对象(充当DAO对象,每个对象提供对不同数据库表的访问)。部署在JBoss AS 7中

然后,我使用EJB3bean方法中的System.identityHashCode添加了代码,以查看EntityManager注入的各种实例(希望在所有DAO中看到相同的实例)。例如:

@Stateless
public class AFacade {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    public List<A> findAll() {
         l.info("entity manager is: "+System.identityHashCode(em)+" class is: "+em.getClass().getSimpleName());
         ...
    }
@无状态
公开课{
@PersistenceContext(unitName=“foo”)
实体管理器;
公共列表findAll(){
l、 信息(“实体管理器是:”+System.identityHashCode(em)+“类是:”+em.getClass().getSimpleName());
...
}
然而,我注意到,每个DAO(例如AFacadeBFacade等等)都被注入了不同的实体管理器(如identityHashCode所报告)尽管PersistenceContext是相同的。但在所有情况下,实现类都是TransactionScopedEntityManager

我不清楚为什么要注入这个不同的EntityManager对象,这是否应该引起我的关注。而且,我知道EJB3容器实际上可能会向真正的EntityManager注入代理,所以这些不同的实例实际上可能是单个EntityMa的代理是的,它们是实体管理器上的代理(事实上,我认为它们是线程安全的装饰器,而不是代理)


我不确定您是否知道EntityManager是连接的包装器。如果您没有此装饰器(或代理),则对无状态bean的所有调用都将共享相同的连接(以及潜在的事务),这不是您想要的。

注入的EntityManager是由EJB容器生成的代理

对于事务范围的实体管理器,每个事务使用一个单独的提供者的实体管理器实例

对该代理进行方法调用时,容器检查javax.transaction.TransactionSynchronizationRegistry(这由EJB容器实现)查看是否已经为此事务创建了提供程序实体管理器。如果没有,它将创建提供程序实体管理器并在TransactionSynchronizationRegistry中注册它,然后将方法调用委托给它。如果已经存在,它将仅检索提供程序实体管理器并将方法调用委托给它

根据Mike Keith和Merrick Schincariol的《Pro JPA2掌握Java持久化API》一书(见第6章),事务范围的EntityManager是无状态的

插入到每个EJB实例对象中的代理对象是不同的,尽管由于事务范围的实体管理器的无状态性质,可能会使用单个代理对象

另请看: