
Named queries
See now how to interrogate our entities. JPA supports different types of query. Here are some:
- Native: These work directly in SQL. All caching is managed by the database.
- Simple: According to the JPA specification, it lets you use Java Persistence Query Language (JPQL), a language that is more object-oriented with respect to SQL. These queries as for the native queries are created at the moment of the query. All caching is managed by the database.
Here is a simple query sample:
TypedQuery<Forum> query = entityManager
.createQuery("select f from Forum f left outer join fetch f.topics where f.id = :forumId", Forum.class);
query.setParameter("forumId", 1);
List<Forum> forumList = query.getResultList();
Named: These are queries created at deploy time at the start of the session factory. They are invoked by name. They are managed in a system caching of the entities very useful for clustering too. The caching system is managed by Infinispan 8.2, a good distributed caching software; Infinispan automatically avoid redundant queries. When you execute a named query, all of the environment is already in session, so it is faster.
Named queries represent a better mode to increase performance in an Entity Manager. See how to use them in the following code block.
Each entity by routine should have its named query declared in its class. Here is a sample for the forum entity:
@NamedQueries({
@NamedQuery(name = "findForumByIdFetchTopics", query = "select f from Forum f left outer "
+ "join fetch f.topics where f.id = :forumId"),
@NamedQuery(name = "findPostsFromCategorydesc", query = "select p from Forum as f join f.topics as "
+ "t join t.posts as p where f.category.id = :categoryId order by p.createDate desc") })
@Entity
...
public class Forum implements Serializable {...}
As you can see, the named queries are declared at the beginning of the class and they are marked with a name. See now how to execute a named query:
@PersistenceContext
private EntityManager entityManager;
...
Query query = entityManager.createNamedQuery("findForumByIdFetchTopics"); query.setParameter("forumId", 2);
List<Forum> forumList = query.getResultList();
The named query since JPA 2.1 can be programmatic. At runtime, you can create a named query and execute it. Here's a sample of creation:
Query query = entityManager.createQuery("select f from Forum f left outer join fetch f.topics where f.id = :forumId");
entityManager.getEntityManagerFactory().addNamedQuery("my_runtime_named_query");
Then it can be called as any named query:
query = entityManager.createNamedQuery("my_runtime_named_query");
query.setParameter("forumId", 1);
forumList = query.getResultList();