jpa 错误“组织.休眠.查询.sqm,第1行:21输入“rtn”不匹配,应为{< EOF>,“,”FROM,GROUP,ORDER,WHERE}”

0x6upsns  于 2023-03-03  发布在  其他
关注(0)|答案(2)|浏览(217)

当我尝试将结果限制为n行时,我遇到了这个错误。
查询在查询属性中定义,这里的方法

  1. public interface PaymentRepositoryJpa extends JpaRepository<Payment, Long> {
  2. @Query("SELECT top(:top) new rtn.domain.common.structs.Payment(p.id, entryDate, paymentDate, ...)"
  3. + " from SomeTable"
  4. + " where p.state = 'P'")
  5. List<Payment> findTopN( @Param("top") int top);

当findTopN被调用时,我得到异常:
错误"组织.休眠.查询. sqm。第1行:21输入"rtn"不匹配,应为{,"," FROM,GROUP,ORDER,WHERE} "
这看起来更像是来自JPA框架的错误,而不是SQL错误。
如果删除top参数,查询将正常工作。
有很多帖子解释了如何限制结果,但是找不到一个结合了构造函数、查询属性和顶级参数的帖子。你知道我做错了什么吗?
我使用的是java spring JPA,版本3.0.3。

beq87vna

beq87vna1#

据我所知,top不是JPQA关键字,它只在支持的DB中本地可用-参见this answer
看起来您的选择是这样,即滥用Pageable

  1. @Query("SELECT new rtn.domain.common.structs.Payment(p.id, entryDate, paymentDate, ...)"
  2. + " from SomeTable"
  3. + " where p.state = 'P'")
  4. List<Payment> findByTopN(Pageable pageable);
  5. }

在服务中,使用PageRequest,返回一个Page对象:

  1. Page<Payment> paymentsPage = paymentRepositoryJpa.findByTop(PageRequest.of(0, top));
  2. List<Payment> payments= paymentsPage.getContent();

或者这个,它利用setMaxResults()

  1. List<Payment> findTopN(@Param("top") int top) {
  2. return entityManager.createQuery("SELECT new rtn.domain.common.structs.Payment(p.id, entryDate, paymentDate, ...)"
  3. + " from SomeTable"
  4. + " where p.state = 'P'",
  5. Payment.class).setMaxResults(top).getResultList();
  6. }
展开查看全部
kxkpmulp

kxkpmulp2#

一种解决方法是像这样使用CriteriaBuilder

  1. public List<Payment> findPendingPayments(int top) {
  2. CriteriaBuilder cb = entityManager.getCriteriaBuilder();
  3. CriteriaQuery<Payment> query = cb.createQuery(Payment.class);
  4. Root<Payment> payment = query.from(Payment.class);
  5. query.select(payment);
  6. return entityManager
  7. .createQuery(query)
  8. .setFirstResult(0) // offset
  9. .setMaxResults(top) // limit
  10. .getResultList();
  11. }

相关问题