Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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
Hibernate 如何绕过计划作业中的LazyInitializationException?_Hibernate_Spring_Lazy Loading - Fatal编程技术网

Hibernate 如何绕过计划作业中的LazyInitializationException?

Hibernate 如何绕过计划作业中的LazyInitializationException?,hibernate,spring,lazy-loading,Hibernate,Spring,Lazy Loading,我正在开发部署在Tomcat上的J2EE服务器应用程序。我使用Spring源代码作为MVC框架,使用Hibernate作为ORM提供程序。我的对象模型有很多惰性关系(依赖对象是根据请求获取的)。高级设计类似于服务级方法调用一些DAO方法来执行数据库操作。服务方法可以从FlexUI调用,也可以作为计划作业调用。当从FlexUI调用它时,服务方法工作正常,即它使用DAO方法获取一些对象,甚至延迟加载也可以。这可以通过使用配置了UI servlet的OpenSessionInViewFilter实现

我正在开发部署在Tomcat上的J2EE服务器应用程序。我使用Spring源代码作为MVC框架,使用Hibernate作为ORM提供程序。我的对象模型有很多惰性关系(依赖对象是根据请求获取的)。高级设计类似于服务级方法调用一些DAO方法来执行数据库操作。服务方法可以从FlexUI调用,也可以作为计划作业调用。当从FlexUI调用它时,服务方法工作正常,即它使用DAO方法获取一些对象,甚至延迟加载也可以。这可以通过使用配置了UI servlet的OpenSessionInViewFilter实现

但当同一个服务方法作为调度作业调用时,它会给出LazyInitializationException。我无法配置OpenSessionInViewFilter,因为没有与之关联的servlet或UI请求

我尝试围绕计划作业方法配置事务,以便服务方法启动事务,所有DAO方法都参与同一事务,希望事务保持活动状态,hibernate会话可用。但它不起作用

请建议是否有人曾经能够得到这样的配置工作。如果需要,我可以发布Hibernate配置和日志消息

非常感谢你的帮助


Shreerang

OpenSessionInViewFilter
是一种黑客行为,不管怎样,过分依赖它是不好的

一个更好的通用解决方案是编写hibernate查询,以便急切地而不是惰性地获取数据。这意味着使用


如果这是不可能或不实际的,那么您的计划任务可以在一段时间内完成整个任务。这将使会话保持打开状态,直到完成。

OpenSessionInViewFilter中的代码并不复杂,我已经成功地修改了源代码以满足自己的需要,它真正需要的是发生延迟加载的线程

我还将Quartz用于许多计划作业,它可以很好地处理容器管理的事务。为了确保在代码退出事务边界之前加载惰性集合,我使用了一个技巧,即创建一个专用方法,在其中调用必要的方法:

@Transactional
private SomeOobj getSomeObj(Long id) {
  SomeObj o = someObjDao.find(id);
  o.getLazyCollection().size(); // <- load the collection
  return o;
}
@Transactional
私有SomeOobj getSomeObj(长id){
SomeObj o=someObjDao.find(id);

o、 getLazyCollection().size();//在阅读了一些Spring事务参考资料之后,我终于能够解决我的问题。 早些时候,我试图编写一个切入点表达式来在事务中运行我的计划jon。但是切入点使用了OR(| |),并且在开始执行时不知何故没有拾取我的方法。因此事务从未打开。(我已经为我的DAO方法提供了一个工作点切割表达式,我正试图在该点切割中添加我的计划方法。)

然后,我找到了一种通过编程打开事务的方法,解决了我的问题。为了其他人的利益,下面是执行此操作的代码片段:

       transactionTemplate.execute(new TransactionCallbackWithoutResult() {
          protected void doInTransactionWithoutResult(TransactionStatus status) {
                // Invoke the real method inside transaction context
                doWork();
          }
        });
有关
TransactionTemplate
的详细信息,请参阅此处的Spring源代码文档:

您能否发布您是如何围绕计划作业包装事务的?哪个部分不起作用?它是否未打开事务或事务是否过早关闭?为了回答您的评论,我尝试使用点切割表达式将计划作业方法包装在其自身的新事务中。但是,点切割没有我总是在开始执行时选择我的方法,因此事务根本没有启动。是的,我试图在事务中执行作业,但无法通过切入点表达式使其工作。事务没有启动。因此我发布了这个问题。但感谢您确认我正朝着正确的方向前进。我正在开始
无法提交,事务现在仅回滚
异常。您知道如何解决此问题吗?