hibernate 关闭多态查询
从网上看来,很多人遇到这样的问题,一般的解决方案是在web层增加一个Filter,管理session的周期,一般的做法是拉长周期,是一次处理期间session一直open,而不是spring所默认的那种,当线程离开service层就关闭。但是这样也会带来很多问题。是single的一个session还是多个?假如是多个,web复杂环境情况,在处理并发的时候,会遇到速度慢的问题。假如使用多个session--即singleSession =false,那样的话,并发量大的时候,session可能占用太多。不太安全。当然我认为这个配置比singleSession =true那种在性能上要好很多。 后来发现三个办法: 一个是最低端的做法,抛弃hibernate的关联配置---即 one-to-many, many-to-one等。自己在dao里写hql或者sql来查询,那样的数据不会又任何问题。但是这样的话,查询会麻烦,多了很多代码,不认识是一种高效率的解决之道,而且放弃了hibernate比较高级的特性,有点暴敛天物的了。 还有一种解决办法是,也是最偷懒的做法,就是把lazy从true该成false,让查询的时候,查询出所有关联的数据。这样其实也是我们所采用的办法,发现做了分页查询,性能还算可以接受。但是发现这样的做法,在一些比较复杂处理操作的时候还是有些问题,比如说batch job。当然这应该算是另外一个问题,具体请看使用hibernate,在面对复杂业务处理的时候,你时候很顺手,由Exception-found shared references to a collection说开去。 第三种做法是,使用一个spring的一个intercepter拦截器来处理,即在service层增加一个拦截器。
这是懒加载的问题,所谓懒加载就是对于关联的表数据并不会立即从数据库中加载出来,而是当你使用它的时候才会从数据库加载,懒加载避免了从数据库中加载过多的无用数据(如果不需要关联数据),在hibernate的映射文件中,默认都是懒加载。
在hibernate映射文件中(如b.hbm.xml)每一个class元素,,(或其他表示多的元素)都会有一个lazy的属性,如
如果你确实需要在整个项目中都需要立即加载,那么可以设置为立即加载,即lazy=false
但是并不建议立即加载,那还有什么办法呢
1,使用它的非getid的方法,如form b获取了b的list,那么遍历一遍list
for(b b : list){
b.geta.getaname();
b.getc.getbname();
}
2,使用hibernate内置的静态方法initialize()
for(b b : list){
hibernate.initialize(b.geta);
hibernate.initialize(b.getc);
}