Autocomplete Annotations

Actions that accept an entity as a parameter provide a mechanism for finding the entity; either a bounded set of choices, or an autocomplete (enter a number of characters and then search for entities that match).

The QueryDSL module provides a simplified way of providing an autocomplete for a given entity class. For each of the properties that should be used in the search, annotated using Property#queryDslAutoComplete().

For example:

@Title
@Column(length = Name.MAX_LEN, nullable = false, name = "name")
@Getter @Setter @ToString.Include
@Property(queryDslAutoComplete = QueryDslAutoCompletePolicy.INCLUDE)    (1)
private String name;
1 property is explicitly searched in any autocomplete query.

If multiple properties have been annotated, then the entered value needs to match any one of the properties (the query performed uses OR, not AND).

The behaviour of the query can be modified in several ways, using various attributes of @DomainObject):

For example, suppose (for some strange reason) that we want to limit the selection only to objects where their attachment property is not populated:

  • specify the additional predicate repository/method:

    @DomainObject(
      queryDslAutoCompleteMinLength = 3,
      queryDslAutoCompleteLimitResults = 30,
      queryDslAutoCompleteAdditionalPredicateRepository = SimpleObjectRepository.class,
      queryDslAutoCompleteAdditionalPredicateMethod = "autoFilter"
    )
    public class SimpleObject implements Comparable<SimpleObject> { /*...*/ }
  • implement the predicate method with the correct signature:

    import com.querydsl.core.types.Predicate;
    import com.querydsl.core.types.dsl.PathBuilder;
    
    @Service
    public class SimpleObjectRepository extends QueryDslRepository<SimpleObject, QSimpleObject> {
    
        //...
    
        public Function<PathBuilder<SimpleObject>, Predicate> autoFilter(
                String search
        ) {
            return so -> so.getString("attachment").isNull();   (1)
        }
    
        //...
    }
    1 In this (silly) example, the auto complete will only propose objects that meet the additional criteria (in this case, that the SimpleObject#attachment property is null).

As a more realistic example, this filter excludes any agreements that are no longer current:

public Function<PathBuilder<Agreement>, Predicate> autoFilter(
        final String searchPhrase
) {
    return a -> a.getDate("endDate", LocalDate.class).isNull()
            .or(a.getDate("endDate", LocalDate.class).goe(clockService.nowAsLocalDate()));
}