Specification: Jakarta Data Version: 1.1 Status: DRAFT Release: August 27, 2026
Copyright
Copyright (c) 2022, 2026 Eclipse Foundation.
Eclipse Foundation Specification License - v1.1
By using and/or copying this document, or the Eclipse Foundation document from which this statement is linked or incorporated by reference, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
Permission to copy, and distribute the contents of this document, or the Eclipse Foundation document from which this statement is linked, in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the document, or portions thereof, that you use:
-
link or URL to the original Eclipse Foundation document.
-
All existing copyright notices, or if one does not exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "Copyright (c) [$date-of-document] Eclipse Foundation AISBL https://www.eclipse.org/legal/efsl.php "
Inclusion of the full text of this NOTICE must be provided. We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof.
No right to create modifications or derivatives of Eclipse Foundation documents is granted pursuant to this license, except anyone may prepare and distribute derivative works and portions of this document in software that implements the specification, in supporting materials accompanying such software, and in documentation of such software, PROVIDED that all such works include the notice below. HOWEVER, the publication of derivative works of this document for use as a technical specification is expressly prohibited.
The notice is:
Disclaimers
The name and trademarks of the copyright holders or the Eclipse Foundation AISBL may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.
1. Introduction
Query by Method Name is a query language suitable for embedding in the names of methods written in Java. As such, its syntax is limited to the use of legal identifier characters, so the text of a query must contain neither whitespace, nor punctuation characters, nor numeric operators, nor comparison operators.
Jakarta Data 1.0 offers a Query by Method Name facility as an extension to the specification, providing a migration path for existing applications written for repository frameworks which offer similar functionality.
@Repository
public interface ProductRepository extends BasicRepository<Product, Long> {
List<Product> findByName(String name);
@OrderBy("price")
List<Product> findByNameLike(String namePattern);
List<Product> findByNameLikeAndPriceLessThanOrderByPriceDesc(String namePattern, float priceBelow);
}
The functionality described here overlaps significantly with both:
-
parameter-based automatic query methods, that is,
@Findand@Delete, and -
annotated query methods, that is
@Queryand Jakarta Common Query Language or Jakarta Persistence Query Language.
Therefore, these alternative approaches are strongly preferred for newly-written code.
A Jakarta Data provider is required to support the Query by Method Name extension in Jakarta Data 1.0.
| A Jakarta Data provider backed by a key-value or wide-column datastore is not required to support Query by Method Name. |
| This functionality is considered deprecated, and the requirement that a provider support the Query by Method Name extension will be removed in a future version of Jakarta Data. |
2. Query by Method Name
In Query by Method Name, a query is expressed via a set of method naming conventions.
A method name is formed by concatenating, in the following order:
-
an action, which must be
find,delete,count, orexists, -
an optional limit,
-
a optional restriction, and
-
an optional order.
2.1. Limits
A find query may have a limit, for example, First or First10. Other actions must not be combined with a limit.
The limit determines the maximum number of records which may be returned by the query. If the query has an order, then the records which are returned are those which occur first after sorting.
2.2. Restrictions
A restriction specifies the criteria used to filter records. It is formed by concatenating By with one or more conditions, delimited by And or Or, for example, PriceLessThanAndNameLike.
Each condition is formed by concatenating, in the following order:
-
an attribute name, which may be a compound name, as specified below in Persistent attribute names in Query by Method Name,
-
optionally,
IgnoreCase(for text-typed attributes), -
optionally,
Not, -
optionally, an operator such as
LessThanorLike.
Absence of an operator implies the equality condition.
The conditions belonging to the restriction determine the parameters of the method, as specified below in Query by Method Name Conditions.
|
When using NoSQL databases, the support for restrictions varies depending on the database type:
|
2.3. Orders
A find query may have an order. The order specifies how records must be sorted. It is formed by concatenating OrderBy with one or more ordered pairs of an entity attribute name and a direction of sorting, Asc or Desc. The direction may be omitted if there is only one entity attribute, in which case Asc is implied.
The order is lexicographic, that is, ordered pairs occurring earlier take precedence. An ordered pair occurring later is only used to resolve "ties" between records which cannot be unambiguously ordered using only earlier ordered pairs.
If no order is specified, the records are not sorted.
|
When using NoSQL databases, sorting support varies by database type:
|
2.4. Example query methods
The following table displays some examples of legal method signatures.
|
Find entities by the |
|
Find entities where |
|
Find entities by the |
|
Find entities by |
|
Find entities by matching the |
2.5. BNF Grammar for Query Methods
The rules for parsing an interpreting a method name are specified by the following grammar.
query : find | action
find : "find" limit? ignoredText? restriction? order?
action : ("delete" | "count" | "exists") ignoredText? restriction?
restriction : "By" predicate
limit : "First" max?
predicate : condition (("And" | "Or") condition)*
condition : attribute "IgnoreCase"? "Not"? operator?
operator
: "Contains"
| "EndsWith"
| "StartsWith"
| "LessThan"
| "LessThanEqual"
| "GreaterThan"
| "GreaterThanEqual"
| "Between"
| "Like"
| "In"
| "Null"
| "True"
| "False"
attribute : identifier ("_" identifier)*
identifier : word
max : digit+
order : "OrderBy" (attribute | orderItem+)
orderItem : attribute ("Asc" | "Desc")
Quoted names are considered case-sensitive keywords.
| Rule name | Explanation |
|---|---|
|
May be a |
|
A |
|
Any other kind of operation has only a restriction to a subset of records. |
|
Restricts the records returned to those which satisfy a predicate |
|
Limits the records retrieved by a |
|
Optional text that does not contain |
|
A filtering criteria, which may include multiple conditions separated by |
|
An attribute of the queried entity and an operator. |
|
An operator belonging to a condition, for example, |
|
An entity attribute name, which can include underscores for nested attributes. |
|
A legal Java identifier, not containing an underscore. |
|
A positive whole number. |
|
Specifies that results of a |
|
An entity attribute used to sort results, where |
2.6. Query by Method Name Keywords
An implementation of Query by Method Name must support the following types of operation.
| Action | Description |
|---|---|
|
Returns entity instances representing the records which satisfy the restriction, or representing all records if there is no restriction. |
|
Deletes every record which satisfy the restriction, or all records if there is no restriction, and returns either no result ( |
|
Returns the number of records which satisfy the restriction, or the total number of records if there is no restriction. |
|
Returns |
An implementation of Query by Method Name must support the following keywords.
| Keyword | Description | Method signature example |
|---|---|---|
|
The |
|
|
The |
|
|
Negates the condition that immediately follows the |
|
|
For a query with ordered results, limits the quantity of results to the number following First, or if there is no subsequent number, to a single result. |
|
|
Specify a static sorting order followed by one or more ordered pairings of an entity attribute name and direction ( |
|
|
Specify a static sorting order of descending. |
|
|
Specify a static sorting order of ascending. |
|
For relational databases, the logical operator And takes precedence over Or, meaning that And is evaluated on conditions before Or when both are specified on the same method. For other database types, the precedence is limited to the capabilities of the database. For example, some graph databases are limited to precedence in traversal order.
An implementation of Query by Method Name backed by a document or graph database is not required to support the First keyword. A repository method must raise java.lang.UnsupportedOperationException or a more specific subclass of the exception if the database does not support this functionality.
|
2.7. Query by Method Name Conditions
In addition to equality conditions, Query by Method Name defines the following kinds of condition.
| Keyword | Attribute type | Parameters | Description | Method signature example |
|---|---|---|---|---|
|
Any sortable type |
2 |
Find results where the attribute is between (inclusive of) two given values, with the first value being the inclusive minimum and the second value being the inclusive maximum. |
|
|
|
1 |
Matches string values with the given substring, which can be a pattern. |
|
|
|
1 |
Matches String values with the given ending, which can be a pattern. |
|
|
Any sortable type |
1 |
Find results where the attribute is less than the given value |
|
|
Any sortable type |
1 |
Find results where the attribute is greater than the given value |
|
|
Any sortable type |
1 |
Find results where the attribute is less than or equal to the given value |
|
|
Any sortable type |
1 |
Find results where the attribute is greater than or equal to the given value |
|
|
|
1 |
Matches string values against the given pattern. |
|
|
|
Requests that string values be compared independent of case for query conditions and ordering. |
|
|
|
Any type |
1 |
Find results where the attribute is one of the values that are contained within the given |
|
|
Any type |
0 |
Finds results where the attribute has a null value. |
|
|
|
1 |
Matches String values with the given beginning, which can be a pattern. |
|
|
|
0 |
Finds results where the attribute has a boolean value of |
|
|
|
0 |
Finds results where the attribute has a boolean value of |
|
Most Query by Method Name conditions require a single repository method parameter. The Between condition requires two parameters. Null, True, and False require none. An In condition requires a parameter of type Set<T> where T is the type of the entity attribute. The repository method parameters used for Query by Method Name conditions follow the order in which the Query by Method Name conditions appear within the method name.
Wildcard characters for patterns are determined by the data store. For relational databases, _ matches any one character and % matches zero or more characters.
An implementation of Query by Method Name backed by a document or graph database is not required to support Contains, EndsWith, StartsWith, Like, IgnoreCase, In, or Null. A repository method must raise java.lang.UnsupportedOperationException or a more specific subclass of the exception if the database does not provide the requested functionality.
|
In the following example the value of the first parameter, namePattern, is used for NameLike, the values of the second and third parameters, minYear and maxYear, are used for YearMadeBetween, and the value of the fourth parameter, maxPrice, is used for PriceLessThan.
List<Product> findByNameLikeAndYearMadeBetweenAndPriceLessThan(String namePattern,
int minYear,
int maxYear,
float maxPrice,
Limit limit,
Order<Product> sortBy)
|
When using NoSQL databases, support for the listed method conditions may vary significantly:
Developers are encouraged to consult the documentation of their chosen NoSQL database provider to confirm the supported operations and clarify the behavior of |
2.8. Return Types
The return type of a Query by Method Name is determined as indicated in the following table, where E is the queried entity type.
| Operation | Return type | Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
For queries returning a single item (or none) |
|
|
For queries where it is possible to return more than one item |
|
|
The caller must call |
|
|
For use with pagination |
|
When working with NoSQL databases, the
|
2.9. Persistent attribute names in Query by Method Name
Section 3.2 of the Jakarta Data specification describes how names are assigned to persistent attributes of an entity.
For Query by Method Name, the use of delimiters within a compound name is optional. Delimiters may be omitted entirely from a compound name when they are not needed to disambiguate the persistent attribute to which the name refers. But for a given name, delimiter usage must be consistent: either the delimiter must be used between every pair of persistent attribute names within the compound name, or it must not occur within the compound name.
Resolution of a persistent attribute involves the following steps:
-
A persistent attribute name is extracted from the method name according to the BNF Grammar for Query Methods. For example, if the query method name is
findByAddressZipCode, the extracted attribute name isAddressZipCode. -
The extracted name is matched against the attributes of the entity class. If the name assigned to a persistent attribute of the entity class matches the extracted name, ignoring case, then the extracted name resolves to that attribute.
-
Otherwise, if no match is found among the attributes of the entity, the extracted name is matched against the attributes of entity classes and embedded classes reachable from the entity class, interpreting the extracted name as a compound name, as outlined in the previous section, both with and without the optional delimiter. If the compound name assigned to a persistent attribute matches the extracted name, also interpreted as a compound name, and ignoring case, then the extracted name resolves to that attribute.
-
If no matching persistent attribute is found in either of the previous steps, the provider is permitted to reject the query method or to throw
UnsupportedOperationExceptionwhen the method is called.
A persistent attribute name used in a Query by Method Name must not contain a keyword reserved by the grammar.
2.9.1. Scenario 1: Person Repository with Unambiguous Resolution
In this scenario, we have the following data model:
class Person {
private Long id;
private MailingAddress address;
}
class MailingAddress {
private int zipcode;
}
The Person entity does not have an addressZipCode attribute, so use of the delimiter is optional. It is valid to write both of the following repository methods, which have the same meaning,
List<Person> findByAddressZipCode(int zipCode);
List<Person> findByAddress_zipcode(int zipCode);
2.9.2. Scenario 2: Customer Repository with Resolution that requires a Delimiter
In this scenario, we have the following data model:
class Customer {
private Long id;
private String addressZipCode;
private MailingAddress address;
}
class MailingAddress {
private int zipcode;
}
The Customer entity has an addressZipCode attribute, as well as an address attribute for an embeddable class with a zipcode attribute. The method name findByAddressZipCode points to the addressZipCode attribute and cannot be used to navigate to the embedded class. To navigate to the zipcode attribute of the embedded class, the delimiter must be used:
List<Customer> findByAddress_zipcode(int zipCode);