JPA CriteriaBuilder泛型错误:CriteriaQuery <capture#2-of?=“”>不适用于参数(Expression <long>)</long> </capture#2-of>

时间:2014-03-05 18:07:03

标签: java generics jpa spring-data-jpa

我是JPA CriteriaBuilder的新手,我遇到了JPA Criteria Queries的泛型错误,我似乎无法理解或无法解决这个问题。我正在尝试将以下查询转换为Criteria查询以在Spring Data存储库中使用:

select * from User where id = ( select max(id) from User);

我尝试根据我在https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria看到的代码执行以下操作,但它给出了编译时错误:

new Specification<User>() {

            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                root = query.from(User.class);
                cb.greatest(root.<Long>get("id"))
                query.select(cb.max(root.<Long>get("id")));
                // TODO Auto-generated method stub
                return null;
            }
        });

当然,我只是意识到,一旦我弄清楚如何指定查询,我甚至不确定如何将其转换为谓词。

我在这里完全偏离基地吗?如何将上述SQL转换为可以使用的谓词?

1 个答案:

答案 0 :(得分:1)

暂时的肮脏的解决方法:

public static User getGreatestId(EntityManager em){
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<User> cq = cb.createQuery(User.class);
    Root<User> userRoot = cq.from(User.class);  
    Path<Long> pathToId = userRoot.get("id");
    cq.select(userRoot).orderBy(cb.desc(pathToId));
    TypedQuery<User> typed = em.createQuery(cq);
    typed.setMaxResults(1);
    return typed.getSingleResult();
}

使用子查询:

 public static User getGreatestId(EntityManager em){
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<User> cq = cb.createQuery(User.class);       
    Root<User> userRoot = cq.from(User.class);  
    Path<Long> pathToId = userRoot.get("id");       
    Subquery<Long> subquery = cq.subquery(Long.class);
    Root<User> subRoot = subquery.from(User.class);
    Path<Long> subPathToId = subRoot.get("id");             
    subquery.select(cb.max(subPathToId));       
    cq.select(userRoot).where(cb.equal(pathToId, subquery));
    TypedQuery<User> typed = em.createQuery(cq);       
    return typed.getSingleResult();
}