ObjectDB ObjectDB

JPA Named Queries

A named query is a statically defined query with a predefined unchangeable query string. Using named queries instead of dynamic queries may improve code organization by separating the JPQL query strings from the Java code. It also enforces the use of query parameters rather than embedding literals dynamically into the query string and results in more efficient queries.

@NamedQuery and @NamedQueries Annotations

The following @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page... annotation defines a query whose name is "Country.findAll" that retrieves all the Country objects in the database:

@NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page...(nameNamedQuery.nameannotation element(Required) The name used to refer to the query with the EntityManager 
 methods that create query objects.See JavaDoc Reference Page...="Country.findAll", queryNamedQuery.queryannotation element(Required) 
 The query string in the Java Persistence query language.See JavaDoc Reference Page...="SELECT c FROM Country c") 

The @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page... annotation contains four elements - two of which are required and two are optional. The two required elements, nameNamedQuery.nameannotation element(Required) The name used to refer to the query with the EntityManager methods that create query objects.See JavaDoc Reference Page... and queryNamedQuery.queryannotation element(Required) The query string in the Java Persistence query language.See JavaDoc Reference Page... define the name of the query and the query string itself and are demonstrated above. The two optional elements, lockModeNamedQuery.lockModeannotation element(Optional) The lock mode type to use in query execution.See JavaDoc Reference Page... and hintsNamedQuery.hintsannotation element(Optional) Query properties and hints.See JavaDoc Reference Page..., provide static replacement for the setLockModesetLockMode(lockMode)Query's methodSet the lock mode type to be used for the query execution.See JavaDoc Reference Page... and setHintsetHint(hintName, value)Query's methodSet a query property or hint.See JavaDoc Reference Page... methods.

Every @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page... annotation is attached to exactly one entity class or mapped superclass - usually to the most relevant entity class. But since the scope of named queries is the entire persistence unit, names should be selected carefully to avoid collision (e.g. by using the unique entity name as a prefix).

It makes sense to add the above @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page... to the Country entity class:

@Entityjavax.persistence.EntityJPA annotationSpecifies that the class is an entity.See JavaDoc Reference Page...
@NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page...(nameNamedQuery.nameannotation element(Required) The name used to refer to the query with the EntityManager 
 methods that create query objects.See JavaDoc Reference Page...="Country.findAll", queryNamedQuery.queryannotation element(Required) 
 The query string in the Java Persistence query language.See JavaDoc Reference Page...="SELECT c FROM Country c") 
public class Country {
  ...
}

Attaching multiple named queries to the same entity class requires wrapping them in a @NamedQueriesjavax.persistence.NamedQueriesJPA annotationSpecifies multiple named Java Persistence query language queries.See JavaDoc Reference Page... annotation, as follows:

@Entityjavax.persistence.EntityJPA annotationSpecifies that the class is an entity.See JavaDoc Reference Page...

@NamedQueries({
    @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page...(nameNamedQuery.nameannotation element(Required) The name used to refer to the query with the EntityManager 
 methods that create query objects.See JavaDoc Reference Page...="Country.findAll",
                queryNamedQuery.queryannotation element(Required) 
 The query string in the Java Persistence query language.See JavaDoc Reference Page...="SELECT c FROM Country c"),
    @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page...(nameNamedQuery.nameannotation element(Required) The name used to refer to the query with the EntityManager 
 methods that create query objects.See JavaDoc Reference Page...="Country.findByName",
                queryNamedQuery.queryannotation element(Required) 
 The query string in the Java Persistence query language.See JavaDoc Reference Page...="SELECT c FROM Country c WHERE c.name = :name"),
}) 
public class Country {
  ...
}
Note: Named queries can be defined in JPA XML mapping files instead of using the @NamedQueryjavax.persistence.NamedQueryJPA annotationSpecifies a static, named query in the Java Persistence query language.See JavaDoc Reference Page... annotation. ObjectDB supports JPA XML mapping files, including the definition of named queries. But, because mapping files are useful mainly for Object Relational Mapping (ORM) JPA providers and less so when using ObjectDB, this alternative is not covered in this manual.

Using Named Queries at Runtime

Named queries are represented at runtime by the same Queryjavax.persistence.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... and TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page... interfaces but different EntityManagerjavax.persistence.EntityManagerJPA interfaceInterface used to interact with the persistence context.See JavaDoc Reference Page... factory methods are used to instantiate them. The createNamedQuerycreateNamedQuery(name, resultClass)EntityManager's methodCreate an instance of TypedQuery for executing a Java Persistence query language named query.See JavaDoc Reference Page... method receives a query name and a result type and returns a TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page... instance:

  TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page...<Country> query =
      em.createNamedQuerycreateNamedQuery(name, resultClass)EntityManager's methodCreate an instance of TypedQuery for executing a
 Java Persistence query language named query.See JavaDoc Reference Page...("Country.findAll", Country.class);
  List<Country> results = query.getResultListgetResultList()TypedQuery's methodExecute a SELECT query and return the query results
 as a typed List.See JavaDoc Reference Page...();

Another form of createNamedQuerycreateNamedQuery(name)EntityManager's methodCreate an instance of Query for executing a named query (in the Java Persistence query language or in native SQL).See JavaDoc Reference Page... receives a query name and returns a Queryjavax.persistence.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... instance:

  Queryjavax.persistence.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... query = em.createNamedQuerycreateNamedQuery(name)EntityManager's methodCreate an instance of Query for executing a named query
 (in the Java Persistence query language or in native SQL).See JavaDoc Reference Page...("Country.findAll");
  List results = query.getResultListgetResultList()Query's methodExecute a SELECT query and return the query results
 as an untyped List.See JavaDoc Reference Page...();

One of the reasons that JPA requires the listing of managed classes in a persistence unit definition is to support named queries. Notice that named queries may be attached to any entity class or mapped superclass. Therefore, to be able to always locate any named query at runtime a list of all these managed persistable classes must be available.

ObjectDB makes the definition of a persistence unit optional. Named queries are automatically searched for in all the managed classes that ObjectDB is aware of, and that includes all the entity classes that have objects in the database. However, an attempt to use a named query still might fail if that named query is defined on a class that is still unknown to ObjectDB.

As a workaround, you may introduce classes to ObjectDB before accessing named queries, by using the JPA 2 Metamodeljavax.persistence.metamodel.MetamodelJPA interfaceProvides access to the metamodel of persistent entities in the persistence unit.See JavaDoc Reference Page... interface. For example:

  em.getMetamodelgetMetamodel()EntityManager's methodReturn an instance of Metamodel interface for access to the
 metamodel of the persistence unit.See JavaDoc Reference Page...().managedTypemanagedType(cls)Metamodel's methodReturn the metamodel managed type representing the 
  entity, mapped superclass, or embeddable class.See JavaDoc Reference Page...(MyEntity.class);

Following the above code ObjectDB will include MyEntity in searching named queries.