Reputation: 213
Currently, the JPA entities that comprise my application have an @NamedQueries block that contains many @NamedQuery annotations. This works well but some of my entities have over 80 @NamedQuery annotations and are getting difficult to maintain. I now need to add sorting to my queries and do not want to create additional @NamedQuery annotations.
During my research, I discover the JPA 2.1 EntityManagerFactory.addNamedQuery method. This seems to be the answer to my prayers. I could create an initializer that runs at startup to create all my named queries using my established naming conventions and eliminate the large @NamedQueries block at the top of my entities.
I could even use the following EclipseLink specific code to add a new NamedQuery based on an existing NamedQuery.
TypedQuery<Portrait> tq = em.createNamedQuery("Portraits.read", Portrait.class);
String jpql = tq.unwrap(EJBQueryImpl.class).getDatabaseQuery().getJPQLString();
Query q = this.em.createQuery(jpql + " ORDER BY p.id DESC");
em.getEntityManagerFactory().addNamedQuery("Portraits.read.Id-D", q);
TypedQuery<Portrait> tq2 = em.createNamedQuery("Portraits.read.Id-D", Portrait.class);
Are there reasons, I should not use the addNamedQuery method instead of or in addition to the @NamedQuery annotation?
Upvotes: 2
Views: 1072
Reputation: 3960
Named queries are used to organizequery definition and improve application performance, because the query string is defined in an annotation and can not be changed at runtime and also prevent security issues like sql injection.
Dynamic Named Queries (addNamedQuery) is a hybrid approach to dynamically create a query and then save it as a named query in the entity manager factory. At that point it becomes just like any other named query that may have been declared statically in metadata.
This is useful in only a few specific cases:
The main advantage it offers is if there are queries that are not known until runtime, but then reissued repeatedly.
Once the dynamic query becomes a named query it will only bear the cost of processing once. It is implementation-specific whether that cost is paid when the query is registered as a named query, or deferred until the first time it is executed.
To summarise it is better to define the namedqueries on the entity class that most directly corresponds to the query result. But dynamic queries also have their place at some specific points.
Upvotes: 5