文档章节

关于Hibernate中fatch=eager的bag集合(一个java List)使用Criteria查询出现重复记录的问题

猪刚烈
 猪刚烈
发布于 2014/10/12 11:40
字数 528
阅读 16
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

关于这个问题在JPwH一书的13.2.3一节中做了详细的描述!

例子:ForumGroup和Forum

 

public class ForumGroup {
 @OneToMany(fetch=FetchType.EAGER,mappedBy="group")
 private List<Forum> forums = new ArrayList<Forum>();
}
public class Forum {
 @ManyToOne(fetch=FetchType.LAZY)
 @JoinColumn(name="groupId",nullable=false)
 @org.hibernate.annotations.ForeignKey(name="fk_Forum_groupId_ForumGroup")
 private ForumGroup group;
}

由于ForumGroup的forums被配制为eager fetch,也就是说在加载ForumGroup时,会同一并把它的所有Forum一起加载出来,这个过程是通过left out join来实现的。下面是hibernate打出的sql.

select
        this_.id as id3_1_,
        this_.creationTime as creation2_3_1_,
        this_.description as descript3_3_1_,
        this_.modifiedTime as modified4_3_1_,
        this_.name as name3_1_,
        forums2_.groupId as groupId3_,
        forums2_.id as id3_,
        forums2_.id as id2_0_,
        forums2_.creationTime as creation2_2_0_,
        forums2_.description as descript3_2_0_,
        forums2_.groupId as groupId2_0_,
        forums2_.modifiedTime as modified4_2_0_,
        forums2_.name as name2_0_
    from
        ForumGroup this_
   
left outer join
        Forum forums2_
            on this_.id=forums2_.groupId

假定有1个ForumGroup,它有3个Forum,上面的sql会生成3条记录。那么Hibernate是如何封装这3条数据的呢?从实际的代码运行结果中可以看到:首先,Hibernate确实只生成了一个ForumGroup的实例和3个Forum的实例。但是如果你使用loadAllForumGroup时,会返回3个ForumGroup的引用,指向同一个ForumGroup的实例!

如果把ForumGroup的forums被配制为lazy fetch,会解决这个问题。但这也只是回避了这个问题!

正确的解决方法是什么呢?

 如果想过滤join和fetch中的重复对象,有两种方法:

1.将续集里封装成set.比如:Set noDupes = new LinkedHashSet(resultList))

2.使用DISTINCT。比如:select distinct i from Item i join fetch i.bids

 

另外一个问题是:

在用JPA进行注释时,如果一个实体里要映射多个集合实体时,我们不能把两个集合的的FetchType设置为EAGER,此时只能设置为LAZY,否则会报:cannot simultaneously fetch multiple bags。或者我们也可以借助:@IndexColumn (加了它就不再是bag集合了,而是list集合了)。也就是说,hibernate不允许一次抓取多个bag.

猪刚烈

猪刚烈

粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
私信 提问
加载中
请先登录后再评论。
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.5K
6
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.1K
3
Flappy Bird(安卓版)逆向分析(一)

更改每过一关的增长分数 反编译的步骤就不介绍了,我们直接来看反编译得到的文件夹 方法1:在smali目录下,我们看到org/andengine/,可以知晓游戏是由andengine引擎开发的。打开/res/raw/at...

enimey
2014/03/04
6K
18
浅入浅出Android(003):使用TextView类构造文本控件

基础: TextView是无法供编辑的。 当我们新建一个项目MyTextView时候,默认的布局(/res/layout/activity_main.xml)中已经有了一个TextView: <TextView 运行效果如下: 修改其文本内容...

樂天
2014/03/22
664
1
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0

没有更多内容

加载失败,请刷新页面

加载更多

将32位循环计数器替换为64位会在Intel CPU上使用_mm_popcnt_u64引起疯狂的性能偏差

问题: I was looking for the fastest way to popcount large arrays of data. 我一直在寻找最快的方法来popcount大量数据的数量。 I encountered a very weird effect: Changing the loop......

javail
57分钟前
17
0
什么是单子? - What is a monad?

问题: Having briefly looked at Haskell recently, what would be a brief, succinct, practical explanation as to what a monad essentially is? 最近对Haskell进行了简要介绍之后,关于......

富含淀粉
今天
19
0
是什么 做?

问题: What's the difference if one web page starts with 如果一个网页以...开头有什么区别 <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=ed......

技术盛宴
今天
15
0
我怎样才能存储特定文件? [重复] - How can I git stash a specific file? [duplicate]

问题: Possible Duplicate: 可能重复: How to stash only one file out of multiple files that have changed 如何从已更改的多个文件中仅存储一个文件 How can I stash a specific file ......

法国红酒甜
今天
36
0
OSChina 周一乱弹 —— 你想用屁治疗一下谁

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《Rain in the Park》- Marika Takeuchi 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
125
3

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部