SwingGUI 2010-05-21
其实,对于Hibernate 的 Lazy
可以说是又爱又恨
不过好像细想,爱是自然,恨嘛... 个人觉得还是恨自己的技术不过关吧
Lazy 懒加载 和 Fetch 抓取
是对相反的东西
用好了相当于可以自由切换Hibernate配置中的 lazy = "xxx" 这个属性
情景:
一个 ACL 有很多 Power ,他们是一 (ACL) 对多 (Power) 关系
所有ACL端有
/** * 权限实体集合 */ @OneToMany( fetch=FetchType.LAZY,mappedBy="theAcl",cascade={CascadeType.REMOVE} ) private Set<Power> powers;
可以看到,上面的Lazy已经是 true ,也就是这个powers会延迟加载
当然,我们可以用抓取fetch把powers强制加载上来
HQL 如下:
from ACL as a inner join fetch a.powers
但是,这样写...加载是加载上来了,但是 ACL 的记录条数重复了
发出的SQL如下:
Hibernate: select acl0_.id as id19_0_, powers1_.id as id24_1_, acl0_.aclName as aclName19_0_, powers1_.isApply as isApply24_1_, powers1_.powerCreate as powerCre3_24_1_, powers1_.powerDelete as powerDel4_24_1_, powers1_.powerLoad as powerLoad24_1_, powers1_.powerName as powerName24_1_, powers1_.theAcl_id as theAcl8_24_1_, powers1_.powerUpdate as powerUpd7_24_1_, powers1_.theAcl_id as theAcl8_0__, powers1_.id as id0__ from t_acl acl0_ inner join t_power powers1_ on acl0_.id=powers1_.theAcl_id
也就是 select 后面,字段上也跟上了 t_power这个表的内容
所以记录会重复...
解决方案就是加上: distinct 关键字
HQL如下:
select distinct a from ACL as a inner join fetch a.powers
也就是让ACL 唯一 (其实就是ACL的主键唯一)
发出SQL如下:
Hibernate: select distinct acl0_.id as id19_0_, powers1_.id as id24_1_, acl0_.aclName as aclName19_0_, powers1_.isApply as isApply24_1_, powers1_.powerCreate as powerCre3_24_1_, powers1_.powerDelete as powerDel4_24_1_, powers1_.powerLoad as powerLoad24_1_, powers1_.powerName as powerName24_1_, powers1_.theAcl_id as theAcl8_24_1_, powers1_.powerUpdate as powerUpd7_24_1_, powers1_.theAcl_id as theAcl8_0__, powers1_.id as id0__ from t_acl acl0_ inner join t_power powers1_ on acl0_.id=powers1_.theAcl_id
成功解决!
PS : 当然我上面用了 inner join fetch,改成left join 更好