文档章节

Hibernate Criteria 查询 出现重复实体

北有风雪
 北有风雪
发布于 2017/02/16 13:50
字数 757
阅读 31
收藏 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进行分页的,由于多端实体只在需要的时候才会加载,所以也算是懒加载的一种方式

© 著作权归作者所有

共有 人打赏支持
北有风雪
粉丝 4
博文 33
码字总数 55091
作品 2
崇明
程序员
私信 提问
关于Hibernate的Criteria查询

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

梦游先生
2013/12/10
0
0
Hibernate 性能优化法则

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

waylau
2016/04/18
184
0
Hibernate的四种查询方式(主键查询,HQL查询,Criteria查询,本地sql查询)和修改和添加

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

别叫小伙
2017/03/09
0
0
Hibernate - DetachedCriteria 的完整用法

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

heroShane
2014/03/05
0
0
Hibernate Criteria 用法

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

chailink
2013/07/20
0
1

没有更多内容

加载失败,请刷新页面

加载更多

[LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)

描述 设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。 如何反序列化或序列化二叉树是没有限制的,你...

honeymose
52分钟前
4
0
java框架学习日志-7(静态代理和JDK代理)

静态代理 我们平时去餐厅吃饭,不是直接告诉厨师做什么菜的,而是先告诉服务员点什么菜,然后由服务员传到给厨师,相当于服务员是厨师的代理,我们通过代理让厨师炒菜,这就是代理模式。代理...

白话
今天
23
0
Flink Window

1.Flink窗口 Window Assigner分配器。 窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。 一种经典的窗口分类可以分成: 翻...

满小茂
今天
18
0
my.ini

1

architect刘源源
今天
16
0
docker dns

There is a opensource application that solves this issue, it's called DNS Proxy Server It's a DNS server that solves containers hostnames, if could not found a hostname that mat......

kut
今天
16
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部