Annotates a repository method as a query method, specifying a query written in Jakarta Data Query Language (JDQL) or in Jakarta Persistence Query Language (JPQL). A Jakarta Data provider is not required to support the complete JPQL language, which targets relational data stores. However, a given provider might offer features of JPQL which go beyond the subset required by JDQL, or might even offer vendor-specific extensions to JDQL which target particular capabilities of the target data store technology. Such extensions come with no guarantee of portability between providers, nor between databases.
The required value()
member specifies the JDQL or JPQL query as a string.
For select
statements, the return type of the query method must be consistent with the type returned by
the query. For update
or delete
statements, it must be void
, int
or long
.
Compared to SQL, JDQL allows an abbreviated syntax for select
statements:
- The
from
clause is optional in JDQL. When it is missing, the queried entity is determined by the return type of the repository method, or, if the return type is not an entity type, by the primary entity type of the repository. - The
select
clause is optional in both JDQL and JPQL. When it is missing, the query returns the queried entity.
A query might involve:
- named parameters of form
:name
where the labelsname
are legal Java identifiers, or - ordinal parameters of form
?n
where the labelsn
are sequential positive integers starting from1
.
A given query must not mix named and ordinal parameters.
Each parameter of an annotated query method must either:
- have exactly the same name (the parameter name in the Java source, or a name assigned by
@Param
) and type as a named parameter of the query, - have exactly the same type and position within the parameter list of the method as a positional parameter of the query, or
- be of type
Limit
,Order
,PageRequest
, orSort
.
The Param
annotation associates a method parameter with a named parameter. The Param
annotation is
unnecessary when the method parameter name matches the name of a named parameter and the application is compiled with
the -parameters
compiler option making parameter names available at runtime.
A method parameter is associated with an ordinal parameter by its position in the method parameter list. The first
parameter of the method is associated with the ordinal parameter ?1
.
For example,
@Repository
public interface People extends CrudRepository<Person, Long>
{ // JDQL with positional parameters@Query("where firstName = ?1 and lastName = ?2")
List<Person>
byName(String first, String last); // JDQL with a named parameter@Query("where firstName || ' ' || lastName like :pattern")
List<Person>
byName(String pattern); // JPQL using a positional parameter@Query("from Person where extract(year from birthdate) = ?1")
List<Person>
bornIn(int year); // JPQL using named parameters@Query("select distinct name from Person where length(name) >= :min and length(name) <= :max")
Page<String>
namesOfLength(@Param
("min") int minLength,@Param
("max") int maxLength,PageRequest<Person>
pageRequest); ... }
A method annotated with @Query
must return one of the following types:
- the query result type
R
, when the query returns a single result, Optional<R>
, when the query returns at most a single result,- an array type
R[]
, List<R>
,Stream<R>
, orPage<R>
orCursoredPage<R>
.
The method returns an object for every query result. If the return type of the annotated method is R
or
Optional<R>
, and the query returns more than one element when executed, the method must throw
NonUniqueResultException
.
A query with an explicit select
clause may return a type other than the entity class, as shown in the
example above, resulting in a Page
parameterized with a query result type different to the queried entity
type when pagination is used. This results in a mismatch between the Page
type returned by the repository
method and the PageRequest
type accepted by the repository method. Therefore, a client must use the method
Page.nextPageRequest(Class)
, explicitly specifying the entity class, to obtain the next page of results. For
example,
Page<String>
page2 = people.namesOfLength(5, 10, page1.nextPageRequest(Person.class));
Annotations such as @Find
, @Query
, @Insert
, @Update
, @Delete
, and
@Save
are mutually-exclusive. A given method of a repository interface may have at most one @Find
annotation, lifecycle annotation, or query annotation.
- See Also:
-
Required Element Summary
-
Element Details
-
value
String valueSpecifies the query executed by the annotated repository method, in JDQL or JPQL.
If the annotated repository method accepts other forms of sorting (such as a parameter of type
Sort
), it is the responsibility of the application programmer to compose the query so that anORDER BY
clause can be validly appended to the text of the query.- Returns:
- the query to be executed when the annotated method is called.
-