Search code examples
hibernatejpasubquery

JPA/hibernate subquery in from clause


We're using JPA with hibernate as the provider, we have a query that contains a join with a subquery in the FROM clause, but we get the following error:

org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 75 [SELECT sd FROM com.hp.amber.datamodel.entities.analysis.SnapshotDates sd, (SELECT max(x.changeDate) maxChangeDate, x.viewId, x.state FROM com.hp.amber.datamodel.entities.analysis.SnapshotDates x WHERE x.changeDate<:date AND x.viewId in (:viewIds) AND x.state=:state GROUP BY x.viewId, x.state) sd2 WHERE sd.viewId = sd2.viewId AND sd.state = :state AND sd.changeDate = sd2.maxChangeDate]

This is the query:

SELECT sd 
FROM SnapshotDates sd, 
     (SELECT max(x.changeDate) maxChangeDate, x.viewId, x.state 
      FROM SnapshotDates x
     WHERE x.changeDate<:date AND x.viewId in (:viewIds) AND x.state=:state
GROUP BY x.viewId, x.state) sd2
WHERE sd.viewId = sd2.viewId 
      AND sd.state = :state 
      AND sd.changeDate = sd2.maxChangeDate

Thank you for helping


Solution

  • Update for Hibernate >= 6.1

    This is possible as of Hibernate 6.1 (released June 14th 2022):

    Long requested support for subqueries (including lateral subqueries) in the from-clause of HQL and Criteria queries

    See example code from a unit test file in the Hibernate repository HQLTest.java:

        @Test
        public void test_hql_derived_root_example() {
            doInJPA(this::entityManagerFactory, entityManager -> {
                //tag::hql-derived-root-example[]
                List<Tuple> calls = entityManager.createQuery(
                    "select d.owner, d.payed " +
                    "from (" +
                    "  select p.person as owner, c.payment is not null as payed " +
                    "  from Call c " +
                    "  join c.phone p " +
                    "  where p.number = :phoneNumber) d",
                    Tuple.class)
                .setParameter("phoneNumber", "123-456-7890")
                .getResultList();
                //end::hql-derived-root-example[]
            });
        }
    

    Older Versions of Hibernate:

    I did not think HQL could do subqueries in the from clause

    https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html#queryhql-subqueries

    note the sentence:

    Note that HQL subqueries can occur only in the select or where clauses.

    I imagine you could change it to a native query and execute it that way.