document Query Validator, and add a TIP about Metamodel

This commit is contained in:
Gavin King 2023-07-13 14:03:17 +02:00
parent 0aa5b5018f
commit 8031952d86
2 changed files with 38 additions and 12 deletions

View File

@ -97,6 +97,21 @@ public abstract class Book_ {
We've already been using metamodel references like `Book_.authors` and `Book.AUTHORS` in the previous chapters.
So now lets see what else the Metamodel Generator can do for us.
[TIP]
====
The Metamodel Generator provides _statically-typed_ access to elements of the JPA `Metamodel`. But the `Metamodel` is also accessible in a "reflective" way, via the `EntityManagerFactory`.
[source,java]
----
EntityType<Book> book = entityManagerFactory.getMetamodel().entity(Book.class);
SingularAttribute<Book,Long> id = book.getDeclaredId(Long.class)
----
// SingularAttribute<Book,String> title = book.getDeclaredSingularAttribute("title", String.class)
This is very useful for writing generic code in frameworks or libraries.
For example, you could use it to create your own criteria query API.
====
Automatic generation of _finder methods_ and _query methods_ is a new feature of Hibernate's implementation of the Metamodel Generator, and an extension to the functionality defined by the JPA specification.
In this chapter, we're going to explore these features.
@ -385,14 +400,6 @@ This lets us declare which associations of `Book` should be pre-fetched by annot
// }
// ----
//
// [TIP]
// ====
// :query-validator: https://github.com/hibernate/query-validator/
//
// Don't like putting queries in annotations?
// No problem.
// If we set up the {query-validator}[Query Validator], we get validation of queries passed as strings directly to the Hibernate session.
// ====
//
// A query method with a similar signature and return type is generated in the corresponding static metamodel class `Queries_`.
// We can call the generated query method like this:
@ -523,4 +530,22 @@ A finder method must return an entity type like `Book`, or a list of the entity
[NOTE]
====
As you might expect, for a reactive session, all query methods and finder methods must return `Uni`.
====
====
[[query-validator]]
=== An alternative approach
:query-validator: https://github.com/hibernate/query-validator/
What if you just don't like the ideas we've presented in this chapter, preferring to call the `Session` or `EntityManager` directly, but you still want compile-time validation for HQL?
Or what if you _do_ like the ideas, but you're working on a huge existing codebase full of code you don't want to change?
Well, there's a solution for you, too.
The {query-validator}[Query Validator] is a separate annotation processor that's capable of type-checking HQL strings, not only in annotations, but even when they occur as arguments to `createQuery()`, `createSelectionQuery()`, or `createMutationQuery()`. It's even able to check calls to `setParameter()`, with some restrictions.
The Query Validator works in `javac`, Gradle, Maven, and the Eclipse Java Compiler.
[CAUTION]
====
Unlike the Metamodel Generator, which is a bog-standard Java annotation processor based on only standard Java APIs, the Query Validator makes use of internal compiler APIs in `javac` and `ecj`. This means it can't be guaranteed to work in every Java compiler. The current release is known to work in JDK 11 and above, though JDK 15 or above is preferred.
====

View File

@ -1041,9 +1041,10 @@ Note that the code which executes the named query is not aware of whether the qu
It's nice to have our queries checked at startup time.
It's even better to have them checked at compile time.
Back in <<generated-query-methods>>, we mentioned that the {query-validator}[Query Validator] can do that for us.
In fact, the Query Validator will even check HQL query strings that occur as arguments to `createQuery()` and friends.
So if we use the Query Validator, there's not much advantage to the use of named queries.
Back in <<generated-query-methods>>, we mentioned that the Metamodel Generator can do that for us, and we presented that as a reason to use `@NamedQuery`.
But actually, Hibernate has a separate <<query-validator,Query Validator>> capable of performing compile-time validation of HQL query strings that occur as arguments to `createQuery()` and friends.
If we use the Query Validator, there's not much advantage to the use of named queries.
====
[[load-access]]