我的JSP页面上出现了could not initialize proxy no Session
异常。
以下是我的工作;
Hibernate有一些DAO。这些不是特殊类别。它们只有Hibernate SessionFactory的自动连接实例。是的,我使用纯Hibernate来访问数据库。
DAO类上的函数用相应准备的@Transactional(rollBackFor=Exception.class)
和My spring配置进行注释。此外,我的实体/控制器也配置了注释等
我没有单独的服务类层。我的服务和DAO是重叠的。它们是一样的。如果服务类需要访问DB,则只使用@Repository
而不是@Service
进行注释
在出现这个错误之前,一切都很顺利。(我有数百个类/DAO/实体等)
现在,我需要在一个控制器上调用两个DAO/Service函数。我只在第一个DAO函数抛出异常时调用第二个DAO。
我需要根据某些条件抛出异常,以回滚第一个DAO调用所做的更改。第二个调用只是向输入错误的用户显示DB中的一些信息。
我不知道为什么,但第二个DAO调用正在工作,它从DB中获取类。然后我将这些类转发到我的控制器上的Model属性,这样我的JSP就可以显示它们。
但是当我的JSP页面试图访问这些类的属性时could not initialize proxy no Session
异常。
所以我的问题是,我应该怎么做才能避免这些错误。
我应该在第一个DAO调用中对hibernate事务/会话做些什么吗?因为我什么都不做。我只是得到一个会话,并在它上获取/保存/更新等。我认为@Transactional
属性将处理事务问题,@Repository
属性将处理会话问题。
我已经尝试过懒惰/急于加载的问题。我已经在我的配置中添加了OpenSessionInViewFilter
过滤器。
但他们都没有解决我的问题。
有什么建议/想法吗?
我现在解决了问题:)
不幸的是,问题是我误解了带有Spring Framework的Hibernate是如何工作的:)
当我比较两个不同Hibernate代理的值时,JSP页面中出现了异常,每个代理都是从单独的Hibernate会话中获取的。
正如我在问题中所描述的,在第一个DAO调用中,我得到了一个代理,然后在第二个DAO呼叫中,我获得了另一个属于不同Hibernate会话的代理。因此,第一个代理是一个带有"关闭会话"的分离hibernate代理,我得到了这个异常。
为了解决这个问题,如果你可以尝试使你的分离代理持久化,然后比较它们的值。
但我通过重构代码来解决这个问题,不打开两个不同的会话来从DB中获取值。
Spring应该使用将初始化事务的代理包装器来包装带有@Transactional注释的服务,因此当您不需要在一个方法中使用多个事务时,您不需要手动执行此操作。
在XML配置中,您需要在每个用@Transactional注释声明bean的XML文件中添加<tx-annotation-driven />
。