![](/img/trans.png)
[英]Pageable + @Query + JOIN (fetch?) in Spring Data don't work
[英]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 中进行分页。
使用两个查询解决此问题的更简单方法
代码示例
@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.