hibernate中lazy与二级缓存问题

语句
from User user left join fetch user.role role

User.hbm.xml设置了cache
Role.hbm.xml设置了cache
user.role的set也已设置了cache,还设置了lazy=true

这条语句第一次运行后被存放到查询缓存,返回List中的每个user对应的role属性都是具体的对象。
这时user和role对象都被存放到了二级缓存。

第二次查询时被查询缓存命中,返回List中的每个User的role是lazy的代理的对象。

因为这时的session已被关闭,我在页面中调用user.role.name时就出错了。no session

我想问,from User user left join fetch user.role role,语句中user对象的role在第一次已被添充到二级缓存,为什么再一次查询时,User的role代理对象,在二级缓存中找不的呢。

User的role是代理对象,这是因为缺省lazy是true,设置false,或者一直打开Session.

在rep里init一把就行了。
拿着spring的话可以 open session in view,但据说有些问题,也没仔细研究过。

关于Open Session in View话题:

在Hibernate社区,"Open Session in View"曾经非常重要,这是因为像Spring这样的框架使用了事务作用域持久化上下文。 所以当未获得的关联被访问时渲染视图将引起 LazyInitializationException 异常。
这个模式通常作为一个跨越整个请求的事务来实现。 此实现方式会有几个问题,其中最严重的是只有我们提交了事务才能确认它成功完成——但在"Open Session in View"的事务提交时,视图已经完全渲染了,甚至渲染好的应答可能已经刷新到客户端。我们怎样才能通知用户他们的事务已失败呢?

在一次webapp请求中openSessionInView可以等效为保持实体的托管状态,那多次请求呢?一次长的业务处理呢?openSessionInView绑定在线程变量上,难道下一个线程还会给同一会话的人吗?

ejb的有状态与和spring的无状态在处理上的不同。Extended persistence context和openSessionInView在状态保存的行为上是相同的,都是最终flush,因为背后的推手都是hibernate思想。但是当建立在ejb的有状态会话bean之上,托管状态不仅可以延续,而且不会因为spring的无状态必须依靠threadLocal而带来的种种不良问题!这时候有状态模型是作为一个独立的单元来进行操做的!我认为无状态问题是迟早要暴露出它的不足的,过多的依赖httpSession只会阻碍业务组件化的发展!

看看jdon的处理方法或者看看seam文档,seam的convernates能做到对绑定在其上的有状态会话bean,在并发会话访问时保证状态的一致性,并对于操作同步执行!
[该贴被oojdon于2008-08-28 01:59修改过]