如何解决防止Hibernate会话通过注释过期? —无法延迟初始化角色的集合
| 我有一个休眠的DAO,当尝试访问返回的bag / Collection对象的成员时,它抛出“无法延迟初始化角色的集合”异常。 我了解引发异常的问题的范围。 Hibernate返回我的对象,对于任何Collections,返回代理对象。在呼叫者中,由于休眠会话已过期,因此当我访问那些代理对象时,将引发此异常。 我想知道的是,如何使用注释使会话不过期?可能吗? 例如,如果我的调用方法是:@RequestMapping(\"refresh.url\")
public ModelAndView refresh(HttpServletRequest request,HttpServletResponse response,int id) throws Exception {
TestObject myObj = testObjDao.get(id);
// throws the exception
myObj.getCollection();
如何使用注解防止此异常?我知道一种解决方案是通过回调扩展休眠会话,该回调在伪代码中可能类似于:
@RequestMapping(\"refresh.url\")
public ModelAndView refresh(HttpServletRequest request,int id) throws Exception {
session = get hibernate session...
session.doInSession(new SessionCallback() {
TestObject myObj = testObjDao.get(id);
// no longer throws the exception
myObj.getCollection();
});
但这在我需要访问集合的所有功能中似乎是重复的。没有办法简单地在上面拍一个@Transactional注释并完成它吗?如:
@RequestMapping(\"refresh.url\")
@Transactional // this doesn\'t extend the session to this method?
public ModelAndView refresh(HttpServletRequest request,int id) throws Exception {
TestObject myObj = testObjDao.get(id);
// throws the exception
myObj.getCollection();
多谢您协助我解释这个问题。
解决方法
您需要执行以下操作:
1)让Spring管理您的交易:
你可以在这里读更多关于它的内容:
http://www.mkyong.com/spring/spring-aop-transaction-management-in-hibernate/
和这里:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative
2)现在,延迟加载:
当您从Hibernate获取对象时,它的所有惰性关联都作为代理返回,然后在访问代理类时会收到异常,因为您的Hibernate会话已关闭。
解决方案是在“视图过滤器/拦截器”中使用打开的会话。
http://www.paulcodding.com/blog/2008/01/21/using-the-opensessioninviewinterceptor-for-spring-hibernate3/
它看起来像这样:
<mvc:interceptors>
<bean class=\"org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor\">
<property name=\"sessionFactory\">
<ref local=\"sessionFactory\"/>
</property>
</bean>
</mvc:interceptors>
希望能帮助到你。
, 休眠会话与网络会话不同,它们不会过期。它们可以通过您的代码或基础架构(例如Spring)手动关闭。
就您而言,不清楚如何首先创建会话,因为如果您不进行会话就输入DAO,则会得到完全不同的异常(No Session Bound to Thread
)。因此,您的会话将以某种方式被创建和关闭。我的大胆猜测是,您的DAO是通过ѭ5或通过拦截器进行事务处理的,因此在您输入会话时会启动会话,而在退出DAO方法时会关闭会话。在这种情况下,只要将DAO上的事务传播设置为PROPAGATION_REQUIRED
,就可以在MVC方法上放置@Transactional
。
但是请记住,您不能将集合带到通过ѭ5注释的方法之外。例如,您不应将其放在http会话中。如果这是要求,则可能需要考虑特殊的DTO对象来复制数据。
, 我使用的解决方案是在DAO中的集合上使用@LazyCollection批注。
@OneToMany(mappedBy = \"<something here>\",cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。