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

时间:2012-09-15 01:57:04

标签: java jpa thread-safety

在我的一个项目中,我试图将持久性的管理从应用程序切换到容器。我正在按照这些说明操作:http://docs.oracle.com/javaee/6/tutorial/doc/gkhrg.html

我已经读过EntityManager不是线程安全的,只是想确保我的设置是正确的。我关注的是:http://weblogs.java.net/blog/2005/12/19/dont-use-persistencecontext-web-app

我有一个产生持久化上下文的类。

@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);
    }

    ....
}

1。这在线程安全性和整体性能方面是一个很好的设置吗?


奖金问题:

JpaResourceProducer我有EntityManager的备用设置,我手动关闭处理中的管理器。

2。容器处理是否自动接近EntityManager

Oracle的示例包含EntityManagerFactory

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

1 个答案:

答案 0 :(得分:0)

你的容器是什么?从使用的注释中我假设它至少兼容Java EE 6 Web Profile,在这种情况下,你会使这个过于复杂。

  1. 本教程介绍了多个持久性单元的产品。这是您的申请中的情况吗?如果不是这样,对EJB的简单注入将更加可靠,并且更少魔法 - 我也不确定单例生成的持久化上下文的事务行为。

  2. Singleton JpaDAO意味着,您的应用程序中一次只能有一个数据库操作,因此这是严重的性能瓶颈。它应该是无状态的(并且通过传统方式注入其持久性上下文)。

  3. 通常,实现DAO和业务逻辑,甚至将JAX-RS端点实现为会话EJB,并让容器正确处理并发和事务。 还可以使用其他示例来源,例如: G。 Adam Bien's JavaEE Patterns