[英]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.