2012-08-07 53 views
6

我的问题很简单,但我不知道如何使Hibernate按我想要的方式工作: - 表MainTable具有带ParentTable的Many-2-One(with 100行)。 MainTable点至m = 26行了100行的在ParentTableHibernate在多对一生成m + 1查询

@ManyToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "PARENT_ID") 
@Fetch(FetchMode.JOIN) 

当我简单地 “从MainTable”

查询它会产生26 + 1查询

当我跟踪查询,该第一个查询只加载26个以后查询使用的PARENT_ID。我想它应该有装载在第一查询整个PARENT_TABLE的方式..

请通过假设帮助:

  • FetchType.EAGER是必须
  • 从MainTable MT使用左连接取mt.parent父是确定的,但我们有很多的关联
+0

避免N + 1选择问题:http://www.realsolve.co.uk/site/tech/hib-tip-pitfall.php?name=n1selects http://stackoverflow.com/questions/97197/what -is-the-n1-selecting-problem – 2012-08-07 18:08:07

+0

@Pangea:谢谢,但在这里有一些评论:1)使用fetch连接是好的,但我们有大约十个父表。这将是最后的解决方案2)我们想要一个类似于在一对多取消选择,以便对MainTable进行1次查询,对于相关表 – 2012-08-08 00:30:01

+0

@Fetch(FetchMode.JOIN)和@Fetch(FetchMode.SELECT)根本没有差异! o_0 – 2012-08-08 00:59:09

回答

3
// Annotate ParentTable Persistance class file with a batch Size 
@BatchSize(size=100) 
class ParentTable{ 
    .. 
} 

@ManyToOne 
@JoinColumn(name = "PARENT_ID") 

这会减少查询次数n/100 + 1。 (我不是在说FetchMode.Lazy)。懒惰模式可以通过使用FetchMode.SUBSELECT排除,仅适用于集合。当涉及到@ManyToOne时,您可以通过指定batchSize来选择batch的数据。

的简短描述大约取为母体Startegies

FetchMode.SUBSELECT

一个查询,对于相关表中的一个查询。 Collections框架仅适用于 。只有2个查询被解雇。

FetchMode.SELECT

一个查询父,N为查询儿童。

FetchMode.JOIN

一个查询的父母,N查询儿童,但数据库检索 发生前期加入。

FetchType.Batch

一个查询父和n/BATCHSIZE + 1个发射查询。


有两种类型获取的基础时,应执行的查询上。

FetchType.EAGER

的查询发射瞬间。

FetchType.LAZY

当子对象被访问时,查询被解雇。因此,执行的查询的数量将取决于访问的子对象的数量 。

How the Fetch Strategies work is better explained here