Module jakarta.data

Annotation Interface Find


@Documented @Retention(RUNTIME) @Target(METHOD) public @interface Find

Annotates a repository method as a parameter-based automatic query method that returns entity instances or entity attribute values.

The Find annotation indicates that the annotated repository method executes a query against a certain entity type, filtering records based on its parameters and the arguments assigned to its parameters.

  • If the method return type involves an entity type, according to the rules specified below, the return type determines the queried entity type.
  • Otherwise, if the method return type does not involve an entity type, the queried entity type is the entity class explicitly specified by the annotation, if any, or the primary entity type of the repository.

The return type of the annotated repository method must involve either:

  • the queried entity type itself,
  • the type of the attribute of the queried entity type specified by the Select annotation, or
  • a Java record type packaging the entity attributes returned by the query. The names and types of the record components must match the names and types of attributes of the queried entity, or the attribute names must be explicitly specified by the Select annotation.

When the return type is not the queried entity type, every returned attribute must be a basic attribute.

Each parameter of the annotated method must either:

  • have exactly the same type and name (the parameter name in the Java source, or a name assigned by @By) as an attribute of the entity class, or
  • have exactly the same name as a persistent attribute of the entity class and be of type C<T>, where C is Constraint or any interface which extends Constraint and T is the type of the persistent attribute,
  • have exactly the same name as a persistent attribute of the entity class, be annotated @Is(C.class), where C is an interface which extends Constraint, and be of the same type as the parameter of a unary static method of C returning C<T> where T is the type of the persistent attribute, or
  • be of type Restriction, Sort, Order, Limit, or PageRequest.

The query is inferred from the method parameters which match attributes of the entity.

There is no specific naming convention for methods annotated with @Find; they may be named arbitrarily, and their names do not carry any semantic meaning defined by the Jakarta Data specification.

For example, consider an interface representing a garage:


 @Repository
 interface Garage {
     @Find
     List<Car> getCarsWithModel(@By("model") String model);
 }
 

The @Find annotation indicates that the getCarsWithModel(model) method retrieves Car instances with the given value of the model attribute.

A method annotated with @Find must return one of the following types, where E is the type returned by the query, either the queried entity type inferred or explicitly specified, the type of the attribute of the entity specified using @Select, or a record type:

  • E, when the method returns a single instance
  • Optional<E>, when the method returns at most a single instance,
  • an array type E[],
  • List<E>,
  • Stream<E>,
  • Page<E>, or
  • CursoredPage<E> (only allowed when E is the entity type).

The number of query results may be limited using the First annotation.

For example, if a Car entity has attribute names including make, model, year, and vin, a repository can use a Java record to request that only a subset of entity attributes be retrieved,


 @Repository
 public interface Cars extends BasicRepository<Car, String> {
     record ModelInfo(String make,
                      String model,
                      int year) {}

     @Find
     Optional<ModelInfo> getModelInfo(@By("vin") String vehicleIdNum);
 }
 

An automatic query method annotated Find returns an entity instance, Java record instance, or entity attribute instance for every database record which satisfies the parameter-based conditions.

  • If the return type of the annotated method is E (the entity type, entity attribute type, or record type) or Optional<E>, and more than one database record satisfies the query conditions, the method must throw NonUniqueResultException.
  • If the return type of the annotated method is E (the entity type, entity attribute type, or record type), and no database record satisfies the query conditions, the method must throw EmptyResultException.

If the Jakarta Data provider is backed by a Jakarta Persistence provider, an automatic query method annotated Find can also be annotated jakarta.persistence.query.ReadQueryOptions to supply additional query options that are specific to Jakarta Persistence.

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:
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Optionally specifies the queried entity type.
  • Element Details

    • value

      Class<?> value

      Optionally specifies the queried entity type.

      The default value, void.class, has the special meaning of determining the entity type from the method return type if the method returns entities, and otherwise from the primary entity type of the repository.

      A repository method with the Find annotation must specify a valid entity class as the value if the method does not return entities and the repository does not otherwise define a primary entity type.

      For example,

      
       @Repository
       public interface Vehicles {
           @Find(Car.class)
           @Select(_Car.PRICE)
           Optional<Float> getPrice(@By(_Car.VIN) String vehicleIdNum);
      
           ...
       }
       
      Default:
      void.class