繁体   English   中英

Hibernate 在查询期间发出警告 - 使用 Pageable 进行左连接获取

[英]Hibernate warn durring query - left join fetch with Pageable

我有两个类与一对多的关系。 User

@Entity
public class User {
    @Id
    private Long id;
    ...
    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
    private Set<Note> notes = new HashSet<>();
    ...
}

Note

@Entity
public class Note {

    @Id
    private Long id;
    ...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
    ...
}

UserRepository ,我想从PagingAndSortingRepository<T, ID>覆盖findAll(Pageable<T> va1)方法以避免 N+1 查询问题。 一切正常,使用以下代码:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    @Override
    @Query(value = "select distinct u from User u left join fetch u.notes")
    Page<User> findAll();
} 

但是当我添加分页时:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    @Override
    @Query(value = "select distinct u from User u left join fetch u.notes",
            countQuery = "select count(u) from User u")
    Page<User> findAll(Pageable page);
}

我在控制台中看到警告:

HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!

我的问题是,如何解决?

当您想通过分页join fetch child 时,Hibernate 执行 SQL 查询而不进行分页意味着获取完整的结果集。 并在 memory 中进行分页。

使用两个查询解决此问题的更简单方法

  • 仅通过分页获取用户 ID
  • 然后用户通过这些 id 使用 IN 查询加入 fetch notes

代码示例

@Query("select u.id from User u")
List<Long> getAllIds(Pageable page);

@Query(value = "select distinct u from User u left join fetch u.notes where u.id IN (:ids)")
List<User> findAll(@Param("ids")List<Long> ids);

这是Blaze-Persistence的完美用例。

Blaze-Persistence 是 JPA 之上的查询构建器,它支持 JPA model 之上的许多高级 DBMS 功能。 它附带的分页支持可以处理您可能遇到的所有问题。

它还具有 Spring 数据集成,因此您可以像现在一样使用相同的代码,您只需添加依赖项并进行设置: https://persistence.blazebit.com/documentation/entity-view/manual/ en_US/index.html#spring-data-setup

Blaze-Persistence 有许多不同的分页策略,您可以配置它们。 默认策略是将 id 查询内联到主查询中。 像这样的东西:

select u 
from User u 
left join fetch u.notes 
where u.id IN (
  select u2.id
  from User u2
  order by ...
  limit ...
)
order by ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM