在我的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.
答案 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”安全。