DAO中的ThreadLocal JPA EntityManager
在我的DAO中的ThreadLocal JPA EntityManager,jpa,dao,entitymanager,thread-local,Jpa,Dao,Entitymanager,Thread Local,在我的DAO类中,我有一个对EntityManager的引用。我想使用ThreadLocal使对EntityManager的访问成为线程安全的 到目前为止,我的尝试只导致了NullPointerExceptions,我似乎找不到一个像样的例子 有人能给我举个例子或者给我指出正确的方向吗 更新:我尝试了BalusC的建议,但当我同时通过JSF和JAX-RS Web服务访问DAO时,仍然会遇到错误: org.hibernate.exception.GenericJDBCException: cou
DAO
类中,我有一个对EntityManager
的引用。我想使用ThreadLocal
使对EntityManager
的访问成为线程安全的
到目前为止,我的尝试只导致了NullPointerException
s,我似乎找不到一个像样的例子
有人能给我举个例子或者给我指出正确的方向吗
更新:我尝试了BalusC的建议,但当我同时通过JSF和JAX-RS Web服务访问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的最后一条评论似乎解决了我的问题:
至少,您不应该在整个应用程序中共享DAO类的单个实例。在每个请求上创建一个新的应用程序。
当您不在EJB应用程序服务器中时,为什么要尝试CDI注入您的EntityManger?只需使用javax.persistence.persistence和持久化单元的名称获取EntityManager工厂,然后使用EMF获取EntityManager,就像在Servlet中一样。使用数据库事务锁来确保对数据库的一致并行访问,不要在java代码中使用EntityManager“线程”安全
我想使用ThreadLocal
使对EntityManager
的访问成为线程安全的
不要那样做。让容器担心这个。我将使您的DAO成为EJB并用于注入。例如
要将其注入JSF托管bean或JAX-RS服务,只需使用:
要控制事务级别,请使用annotation(默认为)。这是否适用于Java EE web应用程序?如果是这样,为什么不使用EJB,通过
@PersistenceContext
注入EntityManager
?这样,所有线程安全和事务性问题都将完全消失,这是针对JSF应用程序+REST Web服务的。使用@PersistenceContext
导致NullPointerException
sIt只能在事务中运行的bean中使用,例如@Stateless
EJB或JSF@ManagedBean
。在所有其他情况下,如“普通”DAO,将不会注入任何内容,因此它将保持null
。谢谢,让它与@ManagedBean
一起工作。还有事务的注释吗?我已经添加了包含注释的jar,但是我仍然得到了TransactionRequiredException
,尽管这些方法标记为@TransactionAttribute
,所以您没有将DAO转换为EJB?您需要手动开始并提交事务。感谢您的帮助,但我仍然怀疑线程问题(原始帖子更新)。这表明JSF和JAX-RS之间共享了相同的DAO实例。每个人都应该有自己的实例。或者,更好的做法是将其作为EJB。那么你就不用担心线程安全和事务性问题了。对,这就解释了。很明显,配置有问题。抱歉,我没有使用EJB/JPA支持手动丰富Tomcat的实践经验,因此我无法提供帮助。我所能做的就是建议你看看Glassfish的网页简介。所有这些都将“仅仅”解决这个问题,而不需要太多的麻烦。否则,也许干脆放弃EJB的想法。至少,您不应该在整个应用程序中共享DAO类的单个实例。在每个请求中创建一个新的。您能否详细说明使用数据库事务锁
?这是评论论坛无法讨论的问题。看看您的entityManager方法,其中一些方法重载为以LockType作为参数。还请阅读以下内容:
@Stateless
public class UserService {
@PersistenceContext
private EntityManager em;
public User find(Long id) {
return em.find(User.class, id);
}
// ...
}
@EJB
private UserService userService;