Close

JPA Criteria API - Applying like() and notLike() Predicate

[Updated: Nov 22, 2018, Created: Nov 6, 2018]

Following example show how to use CriteriaBuilder.like() and CriteriaBuilder.notLike() methods.

These methods determine whether an entity field value satisfies the given pattern (pattern matching rules).

package javax.persistence.criteria;
 ....
public interface CriteriaBuilder {
     ..........
    //like operator with pattern
    Predicate like(Expression<String> x, Expression<String> pattern);
    Predicate like(Expression<String> x, String pattern);
    Predicate notLike(Expression<String> x, Expression<String> pattern);
    Predicate notLike(Expression<String> x, String pattern);
    //like operator with pattern and escape char
    Predicate like(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar);
    Predicate like(Expression<String> x, Expression<String> pattern, char escapeChar);
    Predicate like(Expression<String> x, String pattern, Expression<Character> escapeChar);
    Predicate like(Expression<String> x, String pattern, char escapeChar);
    Predicate notLike(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar);
    Predicate notLike(Expression<String> x, Expression<String> pattern, char escapeChar);
    Predicate notLike(Expression<String> x, String pattern, Expression<Character> escapeChar);
    Predicate notLike(Expression<String> x, String pattern, char escapeChar);
    .................
}

Quick Example

  ....
  CriteriaQuery<Employee> query = ....
  Root<Employee> employee = query.from(Employee.class);
  query.select(employee)
       .where(criteriaBuilder.like(employee.get(Employee_.name),"D%"));
  ....

As first parameter of like/notLike methods are always of String expression, we need to do a type-cast if the target field is not of String type. In following example Employee.salary is of type long:

  ....
  CriteriaQuery<Employee> query = ....
  Root<Employee> employee = query.from(Employee.class);
  query.select(employee)
       .where(criteriaBuilder.like(employee.get(Employee_.salary).as(String.class), "_500" ));
  ....

Following is Expression.as() method signature:

package javax.persistence.criteria;
 ....
public interface Expression<T> extends Selection<T> {
 ....
    /**
     * Perform a typecast upon the expression, returning a new
     * expression object.
     * This method does not cause type conversion:
     * the runtime type is not changed.
     * Warning: may result in a runtime failure.
     * @param type  intended type of the expression
     * @return new expression of the given type
     */
    <X> Expression<X> as(Class<X> type);
}

Criteria Builder also defines following methods involving more restrictive type-casting:

package javax.persistence.criteria;
 ....
public interface CriteriaBuilder {
 ....
//typecasts:
    Expression<Long> toLong(Expression<? extends Number> number);
    Expression<Integer> toInteger(Expression<? extends Number> number);
    Expression<Float> toFloat(Expression<? extends Number> number);
    Expression<Double> toDouble(Expression<? extends Number> number);
    Expression<BigDecimal> toBigDecimal(Expression<? extends Number> number);
    Expression<BigInteger> toBigInteger(Expression<? extends Number> number);
    Expression<String> toString(Expression<Character> character);
 ....
}

Complete Example

Entity

@Entity
public class Employee {
  @Id
  @GeneratedValue
  private long id;
  private String name;
  private String dept;
  private long salary;
    .............
}

Using like() and notLike() methods

public class ExampleMain {
  private static EntityManagerFactory entityManagerFactory =
          Persistence.createEntityManagerFactory("example-unit");

  public static void main(String[] args) {
      try {
          persistEmployees();
          //using like
          findEmployeeBySalary();
          findEmployeeByName();
          //using not like
          findEmployeeByName2();
          //using like with escaping
          findEmployeeByDept();
      } finally {
          entityManagerFactory.close();
      }
  }
    .............
  private static void findEmployeeBySalary() {
      System.out.println("-- Employees with salary LIKE _500 --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(criteriaBuilder.like(
                   employee.get(Employee_.salary).as(String.class), "_500" ));
      entityManager.createQuery(query).getResultList().forEach(System.out::println);
      entityManager.close();
  }

  private static void findEmployeeByName() {
      System.out.println("-- Employees name LIKE D% --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(criteriaBuilder.like(employee.get(Employee_.name),"D%"));
      entityManager.createQuery(query).getResultList().forEach(System.out::println);
      entityManager.close();

  }

  private static void findEmployeeByName2() {
      System.out.println("-- Employees name NOT LIKE D% --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(criteriaBuilder.notLike(employee.get(Employee_.name),"D%"));
      entityManager.createQuery(query).getResultList().forEach(System.out::println);
      entityManager.close();
  }

  private static void findEmployeeByDept() {
      System.out.println("-- Employees dept LIKE '%@_%' ESCAPE '@' --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(criteriaBuilder.like(employee.get(Employee_.dept), "%@_%", '@'));
      entityManager.createQuery(query).getResultList().forEach(System.out::println);
      entityManager.close();
  }
}
-- employees persisted --
Employee{id=1, name='Diana', dept='IT', salary=3000}
Employee{id=2, name='Rose', dept='Sales', salary=2500}
Employee{id=3, name='Denise', dept='Admin', salary=4000}
Employee{id=4, name='Mike', dept='H_R', salary=3500}
-- Employees with salary LIKE _500 --
Employee{id=2, name='Rose', dept='Sales', salary=2500}
Employee{id=4, name='Mike', dept='H_R', salary=3500}
-- Employees name LIKE D% --
Employee{id=1, name='Diana', dept='IT', salary=3000}
Employee{id=3, name='Denise', dept='Admin', salary=4000}
-- Employees name NOT LIKE D% --
Employee{id=2, name='Rose', dept='Sales', salary=2500}
Employee{id=4, name='Mike', dept='H_R', salary=3500}
-- Employees dept LIKE '%@_%' ESCAPE '@' --
Employee{id=4, name='Mike', dept='H_R', salary=3500}

Example Project

Dependencies and Technologies Used:

  • h2 1.4.197: H2 Database Engine.
  • hibernate-core 5.3.7.Final: Hibernate's core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • hibernate-jpamodelgen 5.3.7.Final: Annotation Processor to generate JPA 2 static metamodel classes.
  • JDK 1.8
  • Maven 3.5.4

Applying like() and notLike() Predicate Select All Download
  • jpa-criteria-api-like-restriction
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also