2

在我的DAO课程中,我引用了一个EntityManager. 我想EntityManager通过使用来访问线程安全ThreadLocal

到目前为止,我的尝试只产生了NullPointerExceptions,而且我似乎找不到一个像样的例子。

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

更新:我已经尝试了 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.

4

2 回答 2

5

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

不要那样做。让容器担心这个。我会让你的 DAO 成为@StatelessEJB 并@PersistenceContext用来注入EntityManager. 例如

@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)。

于 2011-09-15T19:45:47.737 回答
0

当您不在 EJB 应用程序服务器中时,为什么要尝试 CDI 注入您的 EntityManger?只需使用 javax.persistence.Persistence 和持久性单元的名称获取您的 EntityManagerFactory,然后使用 EMF 获取您的 EntityManager(s),就像在一个 serverlet 中一样。使用数据库事务锁来确保对数据库的一致并行访问,不要在 java 代码中使 EntityManager “线程”安全。

于 2011-09-15T19:41:43.850 回答