Java 我的@EntityManager线程在servlet容器中是否安全?

Java 我的@EntityManager线程在servlet容器中是否安全?,java,jpa,thread-safety,Java,Jpa,Thread Safety,在我的一个项目中,我试图将持久性管理从应用程序切换到容器。我遵循这些指示: 我读过EntityManager不是线程安全的,只是想确保我的设置是正确的。我关心的是: 我有一个生成持久性上下文的类 @Singleton public class JpaResourceProducer { //The "pu" unit is defined with transaction-type="JTA" @Produces @PersistenceUnit(unitName =

在我的一个项目中,我试图将持久性管理从应用程序切换到容器。我遵循这些指示:

我读过EntityManager不是线程安全的,只是想确保我的设置是正确的。我关心的是:

我有一个生成持久性上下文的类

@Singleton
public class JpaResourceProducer {

    //The "pu" unit is defined with transaction-type="JTA"
    @Produces
    @PersistenceUnit(unitName = "pu")
    @Database
    EntityManagerFactory databasePersistenceUnit;

    @Produces
    @PersistenceContext(unitName = "pu")
    @Database
    EntityManager databaseEntityManager;

    /* Alternative
    @PersistenceContext(unitName = "pu")
    private EntityManager em;

    @Produces
    @UserDatabase
    public EntityManager create() {
        return em;
    }

    public void close(@Disposes @Database EntityManager em) {
        em.close();
    } 
    */
}
然后我有一个注入DAO的jax rs资源

@RequestScoped
@Path("/endpoint")
public class MyResource {

    @Inject private Dao dao;

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public Converter get() {

        MyEntity entity = dao.find(1);

        Converter converter = new Converter(entity);
        return converter;
    }

}
最后是一个
DAO
,在这里我注入了
EntityManager

@Singleton
public class JpaDao<T, K extends Serializable> implements Dao<T, K> {

    protected Class<T> entityClass;

    @Inject
    @Database
    EntityManager em;

    public JpaDao() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
    }

    public T find(K id) {
        return em.find(entityClass, id);
    }

    ....
}
@Singleton
公共类JpaDao实现Dao{
保护类实体类;
@注入
@数据库
实体管理器;
公共JpaDao(){
ParameteredType genericSuperclass=(ParameteredType)getClass().getGenericSuperclass();
this.entityClass=(类)genericSuperclass.getActualTypeArguments()[0];
}
公共找不到(K id){
返回em.find(entityClass,id);
}
....
}
1。就线程安全性和整体性能而言,这是一个良好的设置吗?


奖金问题:

JpaResourceProducer
中,我为
EntityManager
提供了一个替代设置,在该设置中,我手动关闭dispose上的manager

2。my
EntityManager的集装箱装卸是否自动关闭?

Oracle的示例包括一个
EntityManagerFactory


3。当我使用CMP时,我真的需要一个
EntityManagerFactory
吗?

你的容器是什么?从所使用的注释来看,我认为它至少与JavaEE6Web概要文件兼容,在这种情况下,这是过于复杂了

  • 本教程介绍了多个持久性单元的生成。你的申请是这样的吗?如果不是这样的话,简单地注入EJB将更可靠、更不神奇——我也不确定单例生成的持久性上下文的事务行为

  • @Singleton
    public class JpaResourceProducer {
    
        //The "pu" unit is defined with transaction-type="JTA"
        @Produces
        @PersistenceUnit(unitName = "pu")
        @Database
        EntityManagerFactory databasePersistenceUnit;
    
        @Produces
        @PersistenceContext(unitName = "pu")
        @Database
        EntityManager databaseEntityManager;
    
        /* Alternative
        @PersistenceContext(unitName = "pu")
        private EntityManager em;
    
        @Produces
        @UserDatabase
        public EntityManager create() {
            return em;
        }
    
        public void close(@Disposes @Database EntityManager em) {
            em.close();
        } 
        */
    }
    
  • Singleton
    JpaDAO
    意味着,应用程序中一次只能有一个数据库操作,因此这是一个严重的性能瓶颈。它应该是无状态的(并通过传统方式注入持久性上下文)

  • 通常,实现DAO和业务逻辑,甚至将JAX-RS端点作为会话EJB,并让容器正确处理并发性和事务。 也可以使用其他来源的例子,例如。g、