typesafe references to named queries, result set mappings, and entity graphs
Description
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.
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.
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 = session.createNamedQuery(NamedQueries_.bookWithAuthor);
Or:
TypedQuery<Book> q = 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 beObject[]
).If there's no
select
clause at all, the problem is also pretty easy: either you've got afrom
with nojoin
, in which case the thing afterfrom
is the name of the entity, or you have afrom
and ajoin
, in which case you're back toObject[]
.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 toObject
, of course).Ultimately this would be a great feature to contribute back to the JPA spec.