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

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

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

public interface PaymentRepositoryJpa extends JpaRepository<Payment, Long> {

@Query("SELECT top(:top) new rtn.domain.common.structs.Payment(p.id, entryDate, paymentDate, ...)"
            + " from SomeTable" 
            + " where p.state = 'P'")
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

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

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

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

或者这个,它利用setMaxResults()

List<Payment> findTopN(@Param("top") int  top) {
    return entityManager.createQuery("SELECT new rtn.domain.common.structs.Payment(p.id, entryDate, paymentDate, ...)"
            + " from SomeTable" 
            + " where p.state = 'P'",
      Payment.class).setMaxResults(top).getResultList();
}
kxkpmulp

kxkpmulp2#

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

public List<Payment> findPendingPayments(int top) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Payment> query = cb.createQuery(Payment.class);
    Root<Payment> payment = query.from(Payment.class);

    query.select(payment);

    return entityManager
            .createQuery(query)
                .setFirstResult(0) // offset
                .setMaxResults(top) // limit
                .getResultList();
}

相关问题