Hibernate 抓取 去除重复 解决方案

其实,对于Hibernate 的 Lazy

 

可以说是又爱又恨

 

不过好像细想,爱是自然,恨嘛...  个人觉得还是恨自己的技术不过关吧

 

Lazy 懒加载 和 Fetch 抓取

 

是对相反的东西

 

用好了相当于可以自由切换Hibernate配置中的 lazy = "xxx" 这个属性

 

情景:

 

一个 ACL 有很多 Power ,他们是一 (ACL) 对多 (Power) 关系

 

所有ACL端有

Java代码   收藏代码
  1. /** 
  2.      * 权限实体集合 
  3.      */  
  4.     @OneToMany(  
  5.             fetch=FetchType.LAZY,mappedBy="theAcl",cascade={CascadeType.REMOVE}  
  6.         )  
  7.     private Set<Power> powers;  

 

可以看到,上面的Lazy已经是 true ,也就是这个powers会延迟加载

 

当然,我们可以用抓取fetch把powers强制加载上来

 

HQL 如下:

Java代码   收藏代码
  1. from ACL as a inner join fetch a.powers  

 

但是,这样写...加载是加载上来了,但是 ACL 的记录条数重复了

 

发出的SQL如下:

Java代码   收藏代码
  1. Hibernate:   
  2.     select  
  3.         acl0_.id as id19_0_,  
  4.         powers1_.id as id24_1_,  
  5.         acl0_.aclName as aclName19_0_,  
  6.         powers1_.isApply as isApply24_1_,  
  7.         powers1_.powerCreate as powerCre3_24_1_,  
  8.         powers1_.powerDelete as powerDel4_24_1_,  
  9.         powers1_.powerLoad as powerLoad24_1_,  
  10.         powers1_.powerName as powerName24_1_,  
  11.         powers1_.theAcl_id as theAcl8_24_1_,  
  12.         powers1_.powerUpdate as powerUpd7_24_1_,  
  13.         powers1_.theAcl_id as theAcl8_0__,  
  14.         powers1_.id as id0__   
  15.     from  
  16.         t_acl acl0_   
  17.     inner join  
  18.         t_power powers1_   
  19.             on acl0_.id=powers1_.theAcl_id  

 

 

也就是 select 后面,字段上也跟上了 t_power这个表的内容

 

所以记录会重复...

 

解决方案就是加上:  distinct 关键字

 

HQL如下:

Java代码   收藏代码
  1. select distinct a from ACL as a inner join fetch a.powers  

 

 

也就是让ACL 唯一 (其实就是ACL的主键唯一)

 

发出SQL如下:

Java代码   收藏代码
  1. Hibernate:   
  2.     select  
  3.         distinct acl0_.id as id19_0_,  
  4.         powers1_.id as id24_1_,  
  5.         acl0_.aclName as aclName19_0_,  
  6.         powers1_.isApply as isApply24_1_,  
  7.         powers1_.powerCreate as powerCre3_24_1_,  
  8.         powers1_.powerDelete as powerDel4_24_1_,  
  9.         powers1_.powerLoad as powerLoad24_1_,  
  10.         powers1_.powerName as powerName24_1_,  
  11.         powers1_.theAcl_id as theAcl8_24_1_,  
  12.         powers1_.powerUpdate as powerUpd7_24_1_,  
  13.         powers1_.theAcl_id as theAcl8_0__,  
  14.         powers1_.id as id0__   
  15.     from  
  16.         t_acl acl0_   
  17.     inner join  
  18.         t_power powers1_   
  19.             on acl0_.id=powers1_.theAcl_id  

 

成功解决!

 

PS : 当然我上面用了 inner join fetch,改成left join 更好

你可能感兴趣的:(Hibernate)