Cambridge Technology PartnersCommunity Documentation

Chapter 3. Query Method Expressions

3.1. Using method expressions
3.2. Query Ordering
3.3. Nested Properties
3.4. Query Options

Good naming is a difficult aspects in software engineering. A good method name usually makes comments unnecessary and states exactly what the method does. And with method expressions, the method name is actually the implementation!

Let's start by looking at an example:

@Entity

public class Person {
    @Id @GeneratedValue
    private Long id;
    private String name;
    private Integer age;
    private Gender gender;
}
    
public interface PersonDao extends EntityDao<Person, Long> {
    List<Person> findByNameLikeAndAgeBetweenAndGender(String name, 
                                  int minAge, int maxAge, Gender gender);
}    

Looking at the method name, this can easily be read as query all Persons which have a name like the given name parameter, their age is between a min and a max age and having a specific gender. The CDI Query module can translate method names following a given format and directly generate the query implementation out of it (in EBNF-like form):

(Entity|List<Entity>) findBy(Property[Comparator]){Operator Property [Comparator]}

Or in more concrete words:

Other assumptions taken by the expression evaluator:

Following comparators are currently supported to be used in method expressions:

Name# of ArgumentsDescription
Equal1Property must be equal to argument value. If the operator is omitted in the expression, this is assumed as default.
NotEqual1Property must be not equal to argument value.
Like1Property must be like the argument value. Use the %-wildcard in the argument.
GreaterThan1Property must be greater than argument value.
GreaterThanEquals1Property must be greater than or equal to argument value.
LessThan1Property must be less than argument value.
LessThanEquals1Property must be less than or equal to argument value.
Between2Property must be between the two argument values.
IsNull0Property must be null.
IsNotNull0Property must be non-null.

Beside comparators it's also possible to sort queries by using the OrderBy keyword, followed by the attribute name and the direction (Asc or Desc).

public interface PersonDao extends EntityDao<Person, Long> {


    List<Person> findByLastNameLikeOrderByAgeAscLastNameDesc(String lastName);
}    

To create a comparison on a nested property, the traversal parts can be separated by a _:

public interface PersonDao extends EntityDao<Person, Long> {


    List<Person> findByCompany_companyName(String companyName);
}    

CDI Query supports query options on method expressions. If you want to page a query, you can change the first result as well as the maximum number of results returned:

public interface PersonDao extends EntityDao<Person, Long> {


    List<Person> findByNameLike(String name, @FirstResult int start, @MaxResults int pageSize);
}