JPA Named Queries
A named query is a statically defined query with a predefined, unchangeable query string. Using named queries instead of dynamic queries can improve code organization by separating JPQL query strings from Java code. This practice also enforces the use of query parameters instead of embedding literals dynamically into the query string, which results in more efficient queries.
This page covers the following topics:
@NamedQuery and @NamedQueries AnnotationsUsing Named Queries at Runtime@NamedQuery and @NamedQueries Annotations
The following @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language. annotation defines a query named "Country.findAll" that retrieves all Country objects from the database:
@NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language.(namejakarta.persistence.NamedQuery.name(Required) The name used to identify the query in calls to EntityManager.createNamedQuery .="Country.findAll", queryjakarta.persistence.NamedQuery.query(Required) The query string in the Jakarta Persistence query language.="SELECT c FROM Country c")
The @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language. annotation has four elements: two required and two optional. The required elements, namejakarta.persistence.NamedQuery.name(Required) The name used to identify the query in calls to EntityManager.createNamedQuery . and queryjakarta.persistence.NamedQuery.query(Required) The query string in the Jakarta Persistence query language., define the query's name and the query string. The optional elements, lockModejakarta.persistence.NamedQuery.lockMode(Optional) The lock mode type to use in query execution. and hintsjakarta.persistence.NamedQuery.hints(Optional) Query properties and hints., provide a static replacement for the setLockModejakarta.persistence.Query.setLockMode(LockModeType)Set the lock mode type to be used for the query execution. and setHintjakarta.persistence.Query.setHint(String,Object)Set a query property or hint. methods.
Each @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language. annotation is attached to exactly one entity class or mapped superclass, usually the most relevant one. Because the scope of a named query is the entire persistence unit, you should choose names carefully to avoid collisions, for example, by using the unique entity name as a prefix.
For example, you can add the preceding @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language. to the Country entity class:
@Entityjakarta.persistence.EntityDeclares that the annotated class is an entity. @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language.(namejakarta.persistence.NamedQuery.name(Required) The name used to identify the query in calls to EntityManager.createNamedQuery .="Country.findAll", queryjakarta.persistence.NamedQuery.query(Required) The query string in the Jakarta Persistence query language.="SELECT c FROM Country c") public class Country { ... }
To attach multiple named queries to the same entity class, wrap them in a @NamedQueriesjakarta.persistence.NamedQueriesDeclares multiple named Jakarta Persistence query language queries. annotation:
@Entityjakarta.persistence.EntityDeclares that the annotated class is an entity. @NamedQueries({ @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language.(namejakarta.persistence.NamedQuery.name(Required) The name used to identify the query in calls to EntityManager.createNamedQuery .="Country.findAll", queryjakarta.persistence.NamedQuery.query(Required) The query string in the Jakarta Persistence query language.="SELECT c FROM Country c"), @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language.(namejakarta.persistence.NamedQuery.name(Required) The name used to identify the query in calls to EntityManager.createNamedQuery .="Country.findByName", queryjakarta.persistence.NamedQuery.query(Required) The query string in the Jakarta Persistence query language.="SELECT c FROM Country c WHERE c.name = :name"), }) public class Country { ... }
Note: You can also define named queries in JPA XML mapping files instead of using the @NamedQueryjakarta.persistence.NamedQueryDeclares a named query written in the Jakarta Persistence query language. annotation. ObjectDB supports JPA XML mapping files, including the definition of named queries. However, because mapping files are mainly useful for Object-Relational Mapping (ORM) JPA providers and less so for ObjectDB, this manual does not cover that alternative.
Using Named Queries at Runtime
At runtime, named queries are represented by the Queryjakarta.persistence.QueryInterface used to control query execution. and TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries. interfaces, but you use different EntityManagerjakarta.persistence.EntityManagerInterface used to interact with the persistence context. factory methods to instantiate them. The createNamedQueryjakarta.persistence.EntityManager.createNamedQuery(String,Class)Create an instance of TypedQuery<X> for executing a Jakarta Persistence query language named query. method takes a query name and a result type and returns a TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries. instance:
TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries.<Country> query = em.createNamedQueryjakarta.persistence.EntityManager.createNamedQuery(String,Class)Create an instance of TypedQuery<X> for executing a Jakarta Persistence query language named query.("Country.findAll", Country.class); List<Country> results = query.getResultListjakarta.persistence.TypedQuery.getResultList()Execute a SELECT query and return the query results as a typed List<X> .();
Another version of createNamedQueryjakarta.persistence.EntityManager.createNamedQuery(String)Create an instance of Query for executing a named query written in the Jakarta Persistence query language or in native SQL. takes a query name and returns a non-typesafe Queryjakarta.persistence.QueryInterface used to control query execution. instance:
Queryjakarta.persistence.QueryInterface used to control query execution. query = em.createNamedQueryjakarta.persistence.EntityManager.createNamedQuery(String)Create an instance of Query for executing a named query written in the Jakarta Persistence query language or in native SQL.("Country.findAll"); List results = query.getResultListjakarta.persistence.Query.getResultList()Execute a SELECT query and return the query results as an untyped List<E> .();
One reason JPA requires you to list managed classes in a persistence unit definition is to support named queries. Named queries can be attached to any entity class or mapped superclass. Therefore, a list of all managed persistable classes must be available at runtime to locate any named query.
ObjectDB makes the definition of a persistence unit optional. ObjectDB automatically searches for named queries in all the managed classes that it is aware of, which includes all entity classes that have objects in the database. However, an attempt to use a named query might fail if it is defined on a class that is still unknown to ObjectDB.
As a workaround, you can introduce classes to ObjectDB before accessing their named queries by using the JPA 2 Metamodeljakarta.persistence.metamodel.MetamodelProvides access to the metamodel of persistent entities in the persistence unit. interface. For example:
em.getMetamodeljakarta.persistence.EntityManager.getMetamodel()Obtain an instance of the Metamodel interface which provides access to metamodel objects describing the managed types belonging to the persistence unit.().managedTypejakarta.persistence.metamodel.Metamodel.managedType(Class)Return the metamodel managed type representing the entity, mapped superclass, or embeddable class.(MyEntity.class);
After running this code, ObjectDB includes MyEntity when searching for named queries.