diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc index b437d37ec7..326e9ad2cc 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc @@ -1031,8 +1031,7 @@ Next, functions for working with numeric values: | `greatest()` | Return the largest of the given arguments | `greatest(x, y, z)` | Very common in SQL dialects |=== -Finally, functions that evaluate the id, version, or natural id of an entity and the key-column of -a to-one foreign-key: +Finally, functions that evaluate the id, version, or natural id of an entity, or the foreign key of a to-one association: [[hql-model-functions]] |=== @@ -1041,7 +1040,8 @@ a to-one foreign-key: | `id()` | The value of the entity `@Id` attribute. | `version()` | The value of the entity `@Version` attribute. | `naturalid()` | The value of the entity `@NaturalId` attribute. -| `fk()` | The value of the key-column of a `@ManyToOne` (or logical `@ManyToOne`) attribute. Mainly useful with <> +| `fk()` | The value of the foreign key column mapped by a `@ManyToOne` (or logical `@ManyToOne`) association. + Mainly useful with <>. |=== [[hql-user-defined-functions]] @@ -1473,7 +1473,7 @@ See <> for mor [[hql-derived-root]] ==== Derived root -As of Hibernate 6.1, HQL allows to declare derived roots, based on a subquery in the `from` clause. +A _derived root_ is a subquery which occurs in the `from` clause. [[hql-derived-root-example]] ==== @@ -1483,7 +1483,7 @@ include::{sourcedir}/HQLTest.java[tags=hql-derived-root-example, indent=0] ---- ==== -This can be used to split up more complicated queries into smaller parts. +This feature can be used to break a more complicated query into smaller pieces. [[hql-join]] === Declaring joined entities @@ -1644,7 +1644,8 @@ See <> for more information about `treat()`. [[hql-join-derived]] ==== Join subquery -As of Hibernate 6.1, HQL allows against to join sub queries. +A `join` clause may contain a subquery. +This is very similar to a <>. [[hql-derived-join-example]] ==== @@ -1654,16 +1655,14 @@ include::{sourcedir}/HQLTest.java[tags=hql-derived-join-example, indent=0] ---- ==== -This is very similar to defining a <>, but the particular interesting part here, -is the use of the `lateral` keyword, which allows to refer to previous from clause nodes within the subquery. +The `lateral` keyword allows the subquery to refer to aliases defined by previous `from` clauses. This is particularly useful for computing top-N elements of multiple groups. -[NOTE] +[IMPORTANT] ==== -Most databases support lateral natively, but for certain databases it is necessary to emulate this feature. -Beware that the emulation is neither very efficient, nor does it support all possible query shapes, -so be sure to test such queries against your desired target database. +Most databases support `lateral` natively, and Hibernate emulates the feature for databases which don't. +But emulation is neither very efficient, nor does it support all possible query shapes, so it's important to test on your target database. ==== [[hql-implicit-join]] diff --git a/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java b/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java index d82fd21450..da7a6ec01f 100644 --- a/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java @@ -51,7 +51,6 @@ import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.DialectChecks; import org.hibernate.testing.RequiresDialectFeature; -import org.hibernate.testing.orm.junit.DialectFeatureChecks; import org.junit.Before; import org.junit.Test; @@ -3051,15 +3050,15 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase { doInJPA(this::entityManagerFactory, entityManager -> { //tag::hql-derived-root-example[] List 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(); + "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[] }); } @@ -3072,18 +3071,18 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase { doInJPA(this::entityManagerFactory, entityManager -> { //tag::hql-derived-join-example[] List calls = entityManager.createQuery( - "select longest.duration " + - "from Phone p " + - "left join lateral (" + - " select c.duration as duration " + - " from p.calls c" + - " order by c.duration desc" + - " limit 1 " + - " ) longest " + - "where p.number = :phoneNumber", - Tuple.class) - .setParameter("phoneNumber", "123-456-7890") - .getResultList(); + "select longest.duration " + + "from Phone p " + + "left join lateral (" + + " select c.duration as duration " + + " from p.calls c" + + " order by c.duration desc" + + " limit 1 " + + " ) longest " + + "where p.number = :phoneNumber", + Tuple.class) + .setParameter("phoneNumber", "123-456-7890") + .getResultList(); //end::hql-derived-join-example[] }); }