Hibernate OGM MongoDB聚合查询使用JPA分页方法执行异常问题
解决Hibernate OGM聚合查询分页异常的问题
首先,这个问题的核心原因是:Hibernate OGM 5.2.0.Alpha1 在处理MongoDB原生聚合查询时,不会自动将JPA的setFirstResult()和setMaxResults()转换为聚合管道所需的$skip和$limit阶段。而普通的find查询之所以能正常分页,是因为Hibernate OGM可以直接将分页参数映射到MongoDB的skip()和limit()方法上,但聚合查询是基于管道的链式操作,必须显式添加分页阶段。
解决方案:手动在聚合管道中添加分页阶段
你需要修改聚合查询语句,在$match阶段之后加入$skip和$limit两个聚合阶段,替代JPA的分页方法调用。示例代码如下:
// 基础写法:直接拼接分页参数 String query = "db.student.aggregate([{'$match' : {'collegeName' :'VNSGU'}}, {'$skip': " + startPosition + "}, {'$limit': " + noOfRecords + "}])"; List<Student> result = entityManager.createNativeQuery(query, Student.class).getResultList();
如果要避免SQL注入风险,建议使用参数绑定的方式:
// 安全写法:用占位符绑定动态参数 String query = "db.student.aggregate([{'$match' : {'collegeName' :'VNSGU'}}, {'$skip': ?0}, {'$limit': ?1}])"; List<Student> result = entityManager.createNativeQuery(query, Student.class) .setParameter(0, startPosition) .setParameter(1, noOfRecords) .getResultList();
为什么不能直接用JPA的分页方法?
Hibernate OGM的NativeQuery实现对于MongoDB聚合查询的处理逻辑,并没有适配JPA的分页API。当你调用setFirstResult()和setMaxResults()时,底层会尝试对聚合结果做内存分页,但这种处理方式和聚合查询的管道特性冲突,最终导致异常。所以显式在聚合管道中添加$skip和$limit是最可靠的解决方式。
内容的提问来源于stack exchange,提问作者Bharti Ladumor
相关产品推荐
相关产品推荐

