Annotates a repository method as a query method, specifying a query written in Jakarta Common Query Language (JCQL) or in Jakarta Persistence Query Language (JPQL). JCQL and JPQL are defined by the Jakarta Query specification. 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 JCQL, or might even offer vendor-specific extensions to JCQL 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 JCQL 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. An explicit SELECT
clause can be omitted when the query returns the entity or a Java record
for which the record component names all map to entity attribute names,
either by having the same name as the entity attribute or via the record
component being annotated with the Select annotation. For queries
with an explicit select clause:
- if the
selectlist contains more than one item, the query return type must be a Java record type, and the elements of the tuple are repackaged as an instance of the query return type by calling a constructor of the record, passing the elements in the same order they occur in theselectlist, or, - otherwise, when the
selectlist contains only one path expression, the query directly returns the values of the path expression.
For update or delete statements, the return value must
be one of:
voidintorlong, where the value is the number of matching entities. The value might not be precise on databases that provide eventual consistency, in which case some Jakarta Data providers might choose to raiseUnsupportedOperationExceptioninstead of returning an imprecise value.
Compared to SQL, JCQL allows an abbreviated syntax for select
statements:
- The
fromclause is optional in JCQL. 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
selectclause is optional in both JCQL and JPQL. When it is missing, the query returns the queried entity.
A query might involve:
- named parameters of form
:namewhere the labelsnameare legal Java identifiers, or - ordinal parameters of form
?nwhere the labelsnare 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
Restriction,Sort,Order,Limit, orPageRequest.
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> {
// JCQL with positional parameters
@Query("where firstName = ?1 and lastName = ?2")
List<Person> byName(String first, String last);
// JCQL 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 pageRequest,
Order<Person> order);
...
}
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.
The number of query results may be limited using the First annotation.
- If the return type of the annotated method is
RorOptional<R>and more than one record satisfies the query restriction, the method must throwNonUniqueResultException. - If the return type of the annotated method is
Rand no record satisfies the query restriction, the method must throwEmptyResultException.
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
Required Elements
-
Element Details
-
value
String valueSpecifies the query executed by the annotated repository method, in JCQL 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 BYclause can be validly appended to the text of the query.- Returns:
- the query to be executed when the annotated method is called.
-