JPA CriteriaBuilder generics error: CriteriaQuery<capture#2-of ?> is not applicable for the arguments (Expression<Long>)

StackOverflow https://stackoverflow.com/questions/22205684

Question

I'm new to JPA CriteriaBuilder and am running into a generics error with JPA Criteria Queries that I cannot seem to understand or work my way around. I'm trying to translate the following query into a Criteria query to use in a Spring Data repository:

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

I've tried to do the following based on code I've seen at https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria, but it is giving a compile time error:

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;
            }
        });

Of course, I'm just realizing that once I figure out how to specify the query, I'm not even sure how to convert that into a Predicate either.

Am I completely off-base here? How do I convert the above SQL to a Predicate that I can use?

Was it helpful?

Solution

Dirty Workaround for the moment:

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();
}

With Subquery:

 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();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top