Grails GORM:无法初始化代理 - 没有会话
Posted
技术标签:
【中文标题】Grails GORM:无法初始化代理 - 没有会话【英文标题】:Grails GORM: could not initialize proxy - no Session 【发布时间】:2013-04-03 13:27:38 【问题描述】:我有一个结构如下的方法:
public void run()
...
for (...) //this part works correct
User.withTransaction
User user = User.findByUsername(...);
Position pos = Position.findByName(...)
if(pos) ...
else ...
try
pos.save(flush:true);
user.position = pos;
catch (Exception e) ...
...
try
user.save(flush:true, failOnError: true);
catch (Exception e) ...
//this part doesn't work
User.findAll().each
...
if (...)
User.withTransaction
...
//here the operation fails with
//org.hibernate.LazyInitializationException:
//could not initialize proxy - no Session
if (!userDetailsMap.containsKey(it.username)
&& it.userStatus != blocked)
it.userStatus = blocked
it.save(flush:true)
我在这里遇到的异常是代码第二部分中的org.hibernate.LazyInitializationException: could not initialize proxy - no Session
。这里的userStatus
字段是对不同域类的引用。
我尝试在检查属性之前将it.refresh()
和Hibernate.initialize(it)
添加到代码中,但没有用。我在这里做错了什么?
更新:我尝试在检查属性之前调用it.attach
方法,但在方法调用之后it.attached
的值是false
。
【问题讨论】:
你是在视图中调用这个方法吗? @SérgioMichels,不,此方法由调度程序调用。一个任务被添加到调用run()
方法的调度程序中。
【参考方案1】:
Thomas Farvour 指出了正确的方向。文档 13.1.1 Transactions Rollback and the Session 建议以 Eager-fetching 作为最佳解决方案。
【讨论】:
【参考方案2】:当我在一个类中使用子域类时,我遇到了同样的错误,如果您的数据大小超过页面大小,您将收到错误“消息:无法初始化代理 - 无会话”
通过使用 lazy:false,hibernate 将正确使用会话附件并显示适当的数据。
感谢您的这篇文章。我能够解决我的错误。
【讨论】:
【参考方案3】:我认为您没有做任何“错误”,只是对象与休眠会话分离。我会尝试几件事:
将对象附加回休眠会话,如下所示:object.attach() (http://grails.org/doc/2.2.1/ref/Domain%20Classes/attach.html) 使两个域类之间的关联非惰性 (http://grails.org/doc/2.2.x/ref/Database%20Mapping/lazy.html)【讨论】:
我已经尝试添加it.attach()
行,但没有成功。将尝试第二个选项。
这里奇怪的是,在it.attach()
被调用之后,it.attached
的值是假的。
使域类之间的关联变得非惰性最终有所帮助,但我认为这不是最好的解决方案。不过,它是迄今为止唯一的一个。
我遇到了同样的问题(见这里:***.com/questions/15671456/…)。即使我宁愿attach()
对象...,也必须使关系变得不懒惰。
手册中没有指出这一点吗? grails.org/doc/latest/guide/…以上是关于Grails GORM:无法初始化代理 - 没有会话的主要内容,如果未能解决你的问题,请参考以下文章