Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DAO中的ThreadLocal JPA EntityManager_Jpa_Dao_Entitymanager_Thread Local - Fatal编程技术网

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;