如何避免Hibernate出现“由于启用了“在集合获取上分页失败”错误?
我试图在数据库中查询表产品的前5个元素,然后在Spring数据中使用Pageable查询下5个元素。但是我的表产品包含与另一个名为Company的表的关系,因此我也需要执行连接获取来获取公司信息 我的错误失败,因为启用了“在集合获取上分页失败”。我想我理解它为什么会出现这个错误,因为我无法对查询执行连接获取以放入页面,因为这可能包含数百万行 不管怎样,我正在学习这些技术,我正在寻找一种方法使其发挥作用。如果我将查询结果放在产品页面中,如何获取公司信息 以下是我在ProductRepository.java中的操作方法:如何避免Hibernate出现“由于启用了“在集合获取上分页失败”错误?,hibernate,rest,spring-data-jpa,spring-data,Hibernate,Rest,Spring Data Jpa,Spring Data,我试图在数据库中查询表产品的前5个元素,然后在Spring数据中使用Pageable查询下5个元素。但是我的表产品包含与另一个名为Company的表的关系,因此我也需要执行连接获取来获取公司信息 我的错误失败,因为启用了“在集合获取上分页失败”。我想我理解它为什么会出现这个错误,因为我无法对查询执行连接获取以放入页面,因为这可能包含数百万行 不管怎样,我正在学习这些技术,我正在寻找一种方法使其发挥作用。如果我将查询结果放在产品页面中,如何获取公司信息 以下是我在ProductRepository
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
@Query(value = "select distinct product from Product product left join fetch product.companies",
countQuery = "select count(distinct product) from Product product")
Page<Product> findAllWithEagerRelationships(Pageable pageable);
}
在我的productResource.java中:
@GetMapping("/products")
public List<Product> getAllProducts(@RequestParam(required = false, defaultValue = "false") boolean eagerload,
@RequestParam(required = false, defaultValue = "0") int limit,
@RequestParam(required = false, defaultValue = "0") int offset) {
log.debug("REST request to get all Products");
if (limit != 0) {
return productRepository.findAllWithEagerRelationships(PageRequest.of(offset,limit)).getContent();
} else {
return productRepository.findAllWithEagerRelationships();
}
}
My Product.java包含:
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@JoinTable(name = "product_company",
joinColumns = @JoinColumn(name = "product_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "company_id", referencedColumnName = "id"))
private Set<Company> companies = new HashSet<>();
好的,多亏了SternK的评论,我发现,仅仅禁用hibernate.query.fail_on_pagination_over_collection_fetch设置可能不是一个好主意。因此,在一篇链接文章中,我尝试用两个SQL查询修复Hibernate错误,这两个SQL查询可以以读写模式获取实体 下面是我如何使用Spring存储库完成的:
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
@Query(value = "select product.id from Product product order by product.id",
countQuery = "select count(product.id) from Product product")
Page<Long> getProductIds(Pageable pageable);
@Query(value = "select distinct product from Product product left join fetch product.companies where product.id in (:listProducts) order by product.id",
countQuery = "select count(distinct product) from Product product")
List<Product> findAllProducts(@Param("listProducts") List<Long> listProducts);
}
因此,我在一个列表中捕获第一个查询getProductId的结果,并将此列表作为第二个查询findAllProducts的参数传递
希望它能帮助其他人:看看这个,谢谢。工作得很好,我不需要用我的大脑去想它-
@RestController
@RequestMapping("/api")
@Transactional
public class ProductResource {
private final ProductRepository productRepository;
@GetMapping("/products")
public List<Product> getAllProducts(@RequestParam(required = false, defaultValue = "false") boolean eagerload,
@RequestParam(required = false, defaultValue = "0") int limit,
@RequestParam(required = false, defaultValue = "0") int offset) {
log.debug("REST request to get all Products");
List<Long> productIds = productRepository.getProductIds(PageRequest.of(offset,limit, Sort.by("id").ascending())).getContent();
return productRepository.findAllProducts(productIds);
}
}