Currently, named queries, entity graphs, and SQL result set mappings are identified by stringly-typed keys.
It would be better if the metamodel generator would generate a typesafe element that identifies each of these things defined within a certain persistence unit. The reference can in principle even encode the result type of the query.
Thus, you would be able to write:
{{ TypedQuery<Book> q = book session.createNamedQuery(NamedQueries_.bookWithAuthor); }}
Or:
{{ TypedQuery<Book> q = book session.createNativeQuery(sqlQuery, ResultSetMappings_.bookWithAuthor); }}
Or:
{{ Book book = session.find(Book.class, EntityGraphs_.bookWithAuthor); }}
Or whatever, and have that all be completely typesafe.
Now, a challenge for this is how to determine the "return type" for each sort of thing.
- * For `@SqlResultSetMapping` and `@NamedNativeQuery`, it's explicit in the annotation. - * For `@NamedEntityGraph`, it could reasonably be inferred from the entity class on which the annotation occurs. - * For `@NamedQuery` we have a problem.
Now, the query-validator project shows how it's in-principle possible to typecheck a named JPA query at compile time, however, that approach is currently limited to Java 8.
There do seem to be some clever ways to infer the result type of a `@NamedQuery` in specific cases, without typechecking the entire query. For example:
- * If there's more than one element in the `select`, it's totally trivial (must be `Object \ []`). - * If there's no `select` clause at all, the problem is also pretty easy: either you've got a `from` with no `join`, in which case the thing after `from` is the name of the entity, or you have a `from` and a `join`, in which case you're back to `Object \ []`.
However, for the specific case of exactly one element in the `select` clause, we have a problem.
So one option would be to add a result type member to the Hibernate `@NamedQuery` annotation, so that the user can specify it explicitly (defaulting to `Object`, of course).
Ultimately this would be a great feature to contribute back to the JPA spec. |
|