文档章节

Hibernate Criteria 查询 出现重复实体

北有风雪
 北有风雪
发布于 2017/02/16 13:50
字数 757
阅读 29
收藏 0

Hibernate Criteria 查询 出现重复实体

Role与RoleResourcePermission是OneToMany关系,通过Hibernate Criteria查询Role对象时,OUT LEFT JOIN导致Role对象重复

思路

Hibernate的关联查询分为查询和实体包装,left join查询出来的结果本身是不重复的,或者说是只有多端实体不重复,但是Hibernate在做完实体包装之后,因为多端实体被包装成集合,导致生成的最终实体是重复的

解决方法

1、使用DISTINCT_ROOT_ENTITY

Criteria criteria = session.createCriteria(Role.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.list();

通过设置根实体级别的排重得到不重复的实体集合,但是这种方式引入了新的问题。

引入的新问题 1

思路中提到,Hibernate的关联查询分两步,先查询后包装,在使用元查询做分页的时候,maxResults在查询时就已确定,而distinct entity是对实体的操作,所以会导致实际查出来的实体数比maxResults的预期要少。所以在使用这种方式进行查询的时候,不推荐使用元查询的maxResults字段进行分页。

2、设置FetchType.LAYZ

    @OneToMany(fetch = FetchType.LAYZ, mappedBy = "role")

将fetch方式改为懒加载,那么在关联查询的时候,多端对象不会被查出来,只会在用到的时候才会进行查询,这就相当于不进行left join查询了,那么得到的结果也是不重复的,但是这种方式也会引入新的问题。

引入的新问题 2

Hibernate的懒加载是session级别的,目的是用来提升性能。当在同一个session下,直接查询Role实体,实体中不包含多端对象,当需要获取多端对象时Hibernate才会从数据库中进行查询;如果在一个session中查询出Role实体,但是在session关闭之后再去获取多端对象的话,Hibernate则会抛出:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.teemo.entity.Role.resourcePermissions, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:563)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:205)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:542)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:133)
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:163)

3、取消实体之间的非必要join

取消实体之间的非必要join,只在用到的时候才去查询子实体,这样做的好处是既不影响分页,又提升了查询性能,不好的地方是可能需要多次查询

以Role和RoleResourcePermission取消关联关系为例:

  1. 取消Role和RoleResourcePermission的OneToMany关联
  2. 查询Role实体直接返回Role实体集合
  3. 在使用Role实体时,如果需要用到RoleResourcePermission,则根据roleId自行获取RoleResourcePermission集合
  4. 如果不需要使用RoleResourcePermission的话,则不需要进行查询

以上方式因为每次查询都是无关联的实体,所以也就不需要Distinct Entity操作了,即使使用Criteria元查询也是可以使用maxResults进行分页的,由于多端实体只在需要的时候才会加载,所以也算是懒加载的一种方式

© 著作权归作者所有

共有 人打赏支持
北有风雪
粉丝 2
博文 33
码字总数 55091
作品 1
程序员
Hibernate Criteria 用法

Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria 。Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在...

chailink
2013/07/20
0
1
关于Hibernate的Criteria查询

如同大家所了解的Hibernate框架技术是现今的主流SSH之一的技术,Cirteria查询诞生让的我们看到一种全新的方式(不得不说独特),不用自己编写的SQL或HQL(Hibernate Query Languae)语句 (这...

梦游先生
2013/12/10
0
0
Hibernate的四种查询方式(主键查询,HQL查询,Criteria查询,本地sql查询)和修改和添加

Hibernate的添加,修改,查询(三种查询方式)的方法: 案例演示: 1:第一步,导包,老生常谈了都是,省略; 2:第二步,创建数据库和数据表,表结构如下所示: 3:第三步创建实体类User.ja...

别叫小伙
2017/03/09
0
0
Hibernate 性能优化法则

原文同步至: Hibernate 是 Java EE 应用中流行的 JPA 框架,简单易用,但很多使用过 Hibernate 的开发者都普遍反映 Hibernate 性能低下。究其原因,还是使用者没有对 Hibernate 进行过深入理...

waylau
2016/04/18
184
0
Hibernate - DetachedCriteria 的完整用法

现在对 Hibernate的Criteria 的用法进行总结: Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria 。 Criteria 和 DetachedCriteria...

heroShane
2014/03/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

jetbrains系产品IDEA:mac上面提示快捷键设置

原因 由于Mac上面的Ctrl+空格变成输入法切换的快捷键,在使用IDEA的过程中,代码提示很不方便,需要使用option+/这种传统eclipse上面的代码提示快捷键作为主要快捷键。 怎么修改? 移除【opt...

亚林瓜子
32分钟前
0
0
Exclipse 输出结果时换行

System.out.println(f1 + "\n" + d1 + "\n" + d2);

笑丶笑
33分钟前
1
0
怎样治疗标签不能触发onblur事件

I realize this was over a year ago, but it showed up for me in Google while trying to solve this same issue. It seems Chrome does not consider some elements, like body and ancho......

Weijuer
36分钟前
0
0
vue常见库安装

移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击。为了能够立即响应用户的点击事件,才有了FastClick。 安装fastclick npm insta...

林夏夕
38分钟前
0
0
kafka 教程(三) kafka Java API 编程

下午写

MrPei
39分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部