@BatchSize,但在获取@ManyToOne关联时进行许多往返
问题内容:
我将分页与休眠的spring-data-jpa和querydsl一起使用@BatchSize(size=10)
,并且我只用于数据库一次往返。
@Entity
@Table(name = "appel_offre", catalog = "ao")
public class AppelOffre implements java.io.Serializable {
....
@OneToMany(fetch = FetchType.LAZY, mappedBy = "appelOffre")
@BatchSize(size=10)
public Set<AoActivite> getAoActivites() {
return this.aoActivites;
}
和:
@Entity
@Table(name = "ao_activite", catalog = "ao")
public class AoActivite implements java.io.Serializable {
.....
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_ACTIVITE", nullable = false)
@BatchSize(size=10)
public Activite getActivite() {
return this.activite;
}
我的查询
JPAQuery query = new JPAQuery(entityManager).from(ao)
.leftJoin( ao.acheteur, ach ).fetch()
.leftJoin( ao.aoActivites , ao_ac )
.leftJoin( ao_ac.activite , ac )
.offset(...).limit(...).list(..);
但是在日志中有很多往返数据库的行程:
1 - round-trip
.....
Hibernate: select ... from ao.ao_activite aoactivite0_ where aoactivite0_.ID_APPEL_OFFRE in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
2 - round-trip
.....
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
3 - round-trip
.....
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
4 - round-trip
.....
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
5 - round-trip
.....
6 - round-trip
.....
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
7 - round-trip
......
8 - round-trip
.....
Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=?
9 - round-trip
.....
10 - round-trip
问题答案:
该@BatchSize
两个有道理
One-To-Many
和Many-to-One
以及
以防万一Many-To-One
,我们必须在@Entity
级别上应用它(在我们的Activite
类映射中)
@Entity
@BatchSize(size=25)
@Table(name = "activite" ...
public class Activite implements java.io.Serializable {
...
在doc中检查它 ( 在 下面附加小引用) :
[20.1.5。使用批量提取](http://docs.jboss.org/hibernate/orm/4.3/manual/en-
US/html_single/#performance-fetching-batch)
…
批量获取类/实体更容易理解。考虑以下示例:在运行时,您在一个Session中加载了25个Cat实例,每个实例
Cat
都引用了其所有者Person。在Person
类的映射使用了代理服务器,为lazy
=“真”。如果您现在遍历所有的猫并调用getOwner()
它们,默认情况下,Hibernate将执行25条SELECT语句以检索代理的所有者。您可以通过在Person映射中指定一个批处理大小来调整此行为:
<class name="Person" batch-size="10">...</class>
…