1、这个本身是Spring的产物,看看他的原理:
request-->open session-->打开连接、开始事务-->持久操作-->渲染(关闭连接、session)-->response
其中一些过程省略了,不是很关心。
2、看到这个就怀疑了:这样lazy load怎么用?session都闭了,那lazy load从何而来?不是得重新再关联到一个新的session?
请老师和各位道友帮忙解答,谢谢!
请老师和各位道友帮忙解答,谢谢!
Session关闭是在response阶段,也就是http获得返回数据的最后关头才关闭,所以session相当于request scope的长连接,相当于你把jdbc连接在每一次请求request时都一直打开着,直至结果返回浏览器那最后一瞬间关闭。
这无疑是危险的,我们一直强点JDBC连接即用即关,否则,一旦程序出错,内存泄漏相当严重,Hibernate创始人也谈了这个问题,在他的Seam框架中有好的解释。
有些外行人经常将Spring+Hibernate看成黄金组合,实际是跟在老外后面瞎起哄,误导了大批项目和系统。
看看OSIV这个标签中其他更多的讨论。
[该贴被banq于2008-10-15 10:33修改过]
这个session不是http请求的session,实际是一个请求scope内的缓存,如果客户端重新发出请求,那么Hibernate就开始新的session,从数据库中获得,所以一级缓存只是对一个请求命令中一系列处理有作用,而对多次请求的applcation级别则无效,这时要使用二级缓存了,而且是只读操作,所以就不需要事务,可以自己随意配置指定,hibernate没有缺省封装,hibernate缺省封装的一级缓存有事务的,是缓存+事务。
load其实也没有在缓存中查找,其实load是生产了一个代理对象,这个代理对象是原来对象的子类,这样hibernate可以拦截方法调用,当访问对象属性的时候才去真正的查询数据库。而get是直接查询数据库,不生产代理对象。所以load在设置关联的时候非常要用。其中JPA中的getReference和find方法和hibernate的load,get方法的作用是一样的。
Hibernate里一级缓存其实就是persistence context,只有你在一个事务中处理时,一级缓存才起作用。至于OSIV,这个还是和事务有关系。我们一般把事务范围界定在service方法调用前后,当service方法调用后,事务结束了,hibernate 的session就关闭了,所以就要用OSIV将事务边界从service方法扩展到requst的周期。
load其实也没有在缓存中查找,其实load是生产了一个代理对象,这个代理对象是原来对象的子类,这样hibernate可以拦截方法调用,当访问对象属性的时候才去真正的查询数据库。而get是直接查询数据库,不生产代理对象。所以load在设置关联的时候非常要用。其中JPA中的getReference和find方法和hibernate的load,get方法的作用是一样的。
Hibernate里一级缓存其实就是persistence context,只有你在一个事务中处理时,一级缓存才起作用。至于OSIV,这个还是和事务有关系。我们一般把事务范围界定在service方法调用前后,当service方法调用后,事务结束了,hibernate 的session就关闭了,所以就要用OSIV将事务边界从service方法扩展到requst的周期。