Closed gavinking closed 8 months ago
Aaaaactually, forgive me for being slow to see the obvious, but moving in this direction opens up the possibility for even better typesafety. In #459 we added String
-typed references to named queries and named entity graphs to the canonical static metamodel.
But with the proposed introduction of NamedQueryReference
, we could go even further and have typed references to named queries and entity graphs in the static metamodel, so that you would be able to write stuff like:
Book book = em.find(Book_.withAuthors_, bookId);
List<Book> books = em.createNamedQuery(Book_.byTitle_).setParameter(1, title).getResultList();
where Book_.withAuthors_
is a generated reference to a named EntityGraph
and Book_.byTitle_
is a generated reference to a named query.
Now, the caveat here is that our annotations are currently not quite perfect for nailing down the result type of a named JPQL query, but with the addition of an optional member to @NamedQuery
I think we would be good. (We can default to Object
or Object[]
, of course, so no big deal.)
This looks great!
It has always seemed to me that these methods:
really logically belong to
EntityManagerFactory
rather than toEntityManager
, though I definitely see why it makes sense to havegetEntityGraph()
onEntityManager
as a convenience for the most common usage.Relatedly, it seems like an oversight that there's no way to obtain a list of defined named queries from the factory. (And this has come up on #111.)
But I'm not sure precisely what the API should look like here.
First possibility
Naively, perhaps something like:
On the other hand, there's a pretty big asymmetry here if one of these methods returns a list of names, and the other returns a map to the named things.
Second possibility
Another possibility would be to return instances of the defining annotation types:
though perhaps in this approach I would move the methods off of
EntityManagerFactory
to, say,Metamodel
, or perhaps to a newRegistry
object or something.Third possibility
A final (third) possibility would be to introduce some sort of typesafe reference object for named queries, something like
NamedQueryReference<R>
.And then
EntityManagerFactory
would have:And then we would also add the following operation to
EntityManager
:This last option might look a bit convoluted, perhaps, but it comes with some rather nice possibilities for more typesafe usage of this stuff.
At startup time, you could save away references:
and then at runtime you would use them like this:
Reactions?