@BatchSize但在@ManyToOne案例中有很多往返

我使用hibernate 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 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。 使用批量提取

批量获取类/实体更容易理解。 请考虑以下示例:在运行时,您在会话中加载了25个Cat实例,并且每个Cat都有一个对其所有者的引用,即Person。 Person类使用代理映射,lazy =“true”。 如果现在遍历所有cat并在每个getOwner()上调用getOwner() ,默认情况下,Hibernate将执行25个SELECT语句来检索代理所有者。 您可以通过在Person的映射中指定批量大小来调整此行为:

 ... 

  1. @BatchSize对于多对象关联(例如@OneToMany)更有意义,而不是对于一对一的关系。

  2. 对于批量提取,您有(M / N + 1)个数据库往返,其中M是未初始化的多对多关联中的子实体数,N是批量大小。

  3. 如果只需要一个辅助数据库往返,则需要使用子选择提取 。

  4. 对于一对一的关联(例如@ManyToOne),请改用JPQL或Criteria JOIN FETCH 。