???? Hibernate(24): 为什么用DetachedCriteria不能表连接地取数据?中,实验2为了能更好地模拟项目的真实环境, 我把t.commit()一句放到了真正调用wife.getName()语句之前. 抛异常了,org.hibernate.LazyInitializationException!这个很好理解,毕竟这里的Wife对象还只是一个Hibernate创造的代理类对象,也就是并没有真正的数据.但奇怪的是,同样的代码(即在wife.getName()前执行t.commit),有时会抛那个异常,有时就没了.
??? 实验时Main方法里的代码如下:
?? ???? Map wifeMap = (Map) getWife.list().get(0);???? //getWife是DetachedCriteria类型变量?
??? ??? Wife wife = (Wife) wifeMap.get("wifeAlias");??? ??
//??? ??? Hibernate.initialize(wife);??? ??
??? ??? t.commit();??? ??
??? ??? System.out.println("wife's name: "+wife.getName());?
??? 好家伙,一个匪夷所思的问题来, 得查下去.
??? ....
???一番有些"闹心"的排查后,发现是Eclipse的debug功能骗了我:上面说的执行代码不抛异常时都是我用Debug运行时,而且断点是设在wife.getName()执行前的,更"苛刻"的条件是这时在Eclipse里把鼠标停在wifeMap变量上看它属性都是什么内容. 如下图所示:
???这时, 问题通了: 当把鼠标放到wifeMap上看其属性内容时,Hibernate的session还没关,Eclipse会自动用Session把Wife信息(也就是上图中entrySet值)给实例化,这也就是为什么大概一秒后entrySet就有值了. 但正常Run时,就没这回事了, 抛异常也就理所当然了.
???"为什么Eclipse欺骗了我"的问题了, 但这样,项目中的问题还没解决, 怎么办??DetachedCriteria是要在Action中准备好再传给dao的, dao传回来一个代理后,Session就关了,没机会再二次去取Wife信息的.用org.springframework.orm.hibernate3.support.OpenSessionInViewFilter!这样就可以保证在整个Request期间Session都是开着的.