3.3. Customizations

3.3.1. Path initialization

By default Querydsl initializes only direct reference properties. In cases where longer initialization paths are required, these have to be annotated in the domain types via com.mysema.query.annotations.QueryInit usage. QueryInit is used on properties where deep initializations are needed. The following example demonstrates the usage.

@Entity      
class Event {
    @QueryInit("customer")
    Account account;
}      

@Entity
class Account{
    Customer customer;    
}

@Entity
class Customer{
    String name;
    // ...
}

This example enforces the initialization of the account.customer path, when an Event path is initialized as a root path / variable. The path initialization format supports wildcards as well, e.g. "customer.*" or just "*".

The declarative path initialization replaces the manual one, which required the entity fields to be non-final. The declarative format has the benefit to be applied to all top level instances of a Query type and to enable the usage of final entity fields.

3.3.2. Customization of serialization

The serialization of Querydsl can be customized via QuerydslConfig annotations on packages and types. They customize the serialization of the annotated package or type.

The serialization options are entityAccessors to generate accessor methods for entity paths instead of public final fields, listAccessors to generated listProperty(int index) style methods and mapAccessors to generate mapProperty(Key key) style accessor methods.

3.3.3. Custom type mappings

Custom type mappings can be used on properties to override the derived Path type. This can be useful in cases where comparison and String operations should be blocked on certain String paths or Date / Time support for custom types needs to be added. Support for Date / Time types of the Joda time API and JDK (java.util.Date, Calendar and subtypes) is built in, but other APIs might need to be supported using this feature.

The following example demonstrates the usage :

@Entity      
public class MyEntity{      
    @QueryType(PropertyType.SIMPLE)
    public String stringAsSimple;
        
    @QueryType(PropertyType.COMPARABLE)
    public String stringAsComparable;
        
    @QueryType(PropertyType.NONE)
    public String stringNotInQuerydsl;    
}        

The value PropertyType.NONE can be used to skip a property in the Querydsl query type generation. This case is different from @Transient or @QueryTransient annotated properties, where properties are not persisted. PropertyType.NONE just omits the property from the Querydsl query type.

3.3.4. Custom methods

Querydsl provides the possibility to annotate methods for mirroring in query types. Methods can either be annotated directly in the context of the class where they belong or in query extension interfaces, if the target class is only available for annotation.

Example 1

    
public class Point{
  // ...   
}

@QueryExtensions(Point.class)
public interface PointOperations {

   @QueryMethod("geo_distance({0}, {1})")
   int geoDistance(Point otherPoint);

}    

The first example describes indirect annotation via QueryExtensions usage. Let's assume that Point is a class of an external library which has to be used as such without the possibility of customization.

To make a geoDistance(Point) method available in Querydsl query type for Point, a query extension interface is used. Via the QueryExtensions annotation the interface is bound to the Point class and via the QueryMethod annotation the geoDistance method is declared to be mirrored into the Point query type with a serialization pattern of "geo_distance({0}, {1})".

The serialization patterns of query methods have the host object it self always as the first argument and the method parameters as further arguments.

Example 2

public class Point{

    @QueryMethod("geo_distance({0}, {1})")
    int geoDistance(Point otherPoint){
       // dummy implementation
        return 0;
    }
   
}

The second example features the same use case as in the first example, but this time the Point class is annotated directly. This approach is feasible, if the related domain type is available for annotation and APT post processing.