我使用具有規範和分頁功能的Spring Data JPA存儲庫實現了實體列表的搜索/過濾服務。我試圖減少查詢數量(n + 1問題)並使用標準提取機制獲取嵌套數據。Spring Data JPA repository with specification,pagination and criteria fetch-join
我有兩個實體類:
@Entity
@Table(name = "delegations")
public class Delegation {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne
private Customer customer;
// more fields, getters, setters, business logic...
}
和
@Entity
@Table(name = "customers")
public class Customer {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
// more fields, getters, setters, business logic...
}
DTO過濾器類:
public class DelegationFilter {
private String customerName;
// more filters, getters, setters...
}
和搜索/過濾服務:
public class DelegationService {
public Page<Delegation> findAll(DelegationFilter filter, Pageable page) {
Specifications<Delegation> spec = Specifications.where(
customerLike(filter.getCustomerName())
);
return delegationRepository.findAll(spec, page);
}
public List<Delegation> findAll(DelegationFilter filter) {
Specifications<Delegation> spec = Specifications.where(
customerLike(filter.getCustomerName())
);
return delegationRepository.findAll(spec);
}
private Specification<Delegation> customerLike(String customerName) {
return (root, query, cb) -> {
Join<Delegation,Customer> join = (Join) root.fetch(Delegation_.customer);
return cb.like(cb.lower(join.get(Customer_.name)), addWildCards(customerName.toLowerCase()));
};
}
private static String addWildCards(String param) {
return '%' + param + '%';
}
}
問題:
當我打電話findAll(DelegationFilter filter, Pageable page)
我得到異常:
org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.QueryException: query specified join fetching, but the owner
of the fetched association was not present in the select list
有沒有辦法解決這個問題的方法嗎?
findAll(DelegationFilter filter)
(無分頁方法)的作品般的魅力......只使用join
(不含fetch
)也能正常工作(即使有分頁)
我知道,有對JPQL的解決方案: Spring-Data FETCH JOIN with Paging is not working 但我想堅持使用標準的API ...
我使用Spring 1.4啓動(春4.3.2,彈簧數據的JPA 1.10.2)和Hibernate 5.0.9
看起來很醜:)但看起來像解決方案...謝謝:) –