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 更好