DAO中的ThreadLocal JPA EntityManager

时间:2011-09-15 19:17:29

标签: jpa dao entitymanager thread-local

在我的DAO课程中,我引用了EntityManager。我想使用EntityManager来访问ThreadLocal线程安全的访问权限。

到目前为止,我的尝试只导致NullPointerException s,我似乎无法找到一个不错的例子。

有人可以给我一个例子或指出我正确的方向吗?

更新:我已经尝试过BalusC的建议,但是当我同时通过JSF和JAX-RS网络服务访问DAO时,我仍然遇到错误:

 org.hibernate.exception.GenericJDBCException: could not load an entity
 java.sql.SQLException: You can't operate on a closed Connection!!!
 java.lang.NullPointerException
    at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareStatement

我正在使用C3P0,所以我不知道为什么关闭连接是一个问题。

update2 :BalusC的最后评论似乎解决了我的问题:At least, you should not have a single instance of the DAO class shared throughout the application. Create a new one on every request.

2 个答案:

答案 0 :(得分:5)

  

我想使用EntityManager来访问ThreadLocal线程安全。

不要那样做。让容器担心这一点。我将您的DAO设为@Stateless EJB并使用@PersistenceContext注入EntityManager。 E.g。

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    public User find(Long id) {
        return em.find(User.class, id);
    }

    // ...
}

要将其注入JSF托管bean或JAX-RS服务,只需使用@EJB

@EJB
private UserService userService;

要控制交易级别,请使用@TransactionAttribute注释(默认为TransactionAttributeType#REQUIRED)。

答案 1 :(得分:0)

当您不在EJB应用服务器中时,为什么要让CDI注入您的EntityManger?只需使用javax.persistence.Persistence和持久性单元的名称抓住您的EntityManagerFactory,然后使用EMF获取您的EntityManager,就像在servlet中那样。使用数据库事务锁来确保对db的一致并行访问,不要在Java代码中使EntityManager“thread”安全。