Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Criteria select all instances with max values in their groups

Is there a way to write with JPA 2 CriteriaBuilder the equivalent of the following query?

select * from season s1
where end = (
    select max(end)
    from season s2
    where s1.contest_id=s2.contest_id
);

In JPQL this query is:

Select s1 from Season s1 
where s1.end = (
    select max(s2.end)
    from Season s2
    where s1.contest=s2.contest
)
like image 842
Ivan Sopov Avatar asked Jan 18 '13 14:01

Ivan Sopov


People also ask

What is CriteriaBuilder in JPA?

CriteriaBuilderJPA interfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings. See JavaDoc Reference Page... interface serves as the main factory of criteria queries and criteria query elements. It can be obtained either by the EntityManagerFactory. persistence.

What is used to fetch the maximum number of rows to be returned by the criteria query?

Description. The SQL SELECT LIMIT statement is used to retrieve records from one or more tables in a database and limit the number of records returned based on a limit value.

What is the use of CriteriaBuilder in Hibernate?

Interface CriteriaBuilder. Used to construct criteria queries, compound selections, expressions, predicates, orderings. Note that Predicate is used instead of Expression<Boolean> in this API in order to work around the fact that Java generics are not compatible with varags.

Is Hibernate Criteria deprecated?

Since Hibernate 5.2, the Hibernate Criteria API is deprecated, and new development is focused on the JPA Criteria API. We'll explore how to use Hibernate and JPA to build Criteria Queries.


1 Answers

This should work, with contest being either a basic Integer property, or a ManyToOne property pointing to another non-basic Entity.

EntityManger em;      //to be injected or constructed

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Season> cq = cb.createQuery(Season.class);
Subquery<Date> sq = cq.subquery(Date.class);
Root<Season> s1 = cq.from(Season.class);
Root<Season> s2 = sq.from(Season.class);
sq.select(cb.greatest(s2.get(Season_.end)));
sq.where(cb.equal(s2.get(Season_.contest), s1.get(Season_.contest)));
cq.where(cb.equal(s1.get(Season_.end), sq));
List<Season> result = em.createQuery(cq).getResultList();
like image 79
perissf Avatar answered Sep 24 '22 17:09

perissf