Close

JPA Criteria API - Applying isMember() and isNotMember() Predicate

[Updated: Oct 22, 2018, Created: Oct 22, 2018]

Following example shows how to use CriteriaBuilder.isMember() and CriteriaBuilder.isNotMember() methods.

These methods determine whether a value is an element of a collection.

package javax.persistence.criteria;
 ......
public interface CriteriaBuilder{
 ......
 <E, C extends Collection<E>> Predicate isMember(Expression<E> elem, Expression<C> collection);
 <E, C extends Collection<E>> Predicate isMember(E elem, Expression<C> collection);
 <E, C extends Collection<E>> Predicate isNotMember(Expression<E> elem, Expression<C> collection);
 <E, C extends Collection<E>> Predicate isNotMember(E elem, Expression<C> collection);
 ......
}

Quick Example

   CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
   Root<Employee> employee = criteriaQuery.from(Employee.class);
   criteriaQuery.select(employee)
                .where(criteriaBuilder.isMember(criteriaBuilder.literal("222-222-222"),
                                                    employee.get(Employee_.phoneNumbers)));
  TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);
  List<Employee> list = typedQuery.getResultList();

In above example criteriaBuilder.literal() returns Expression. We can also use the other overloaded method of isMember() which takes element value instead of Expression:

......
  criteriaQuery.select(employee)
               .where(criteriaBuilder.isMember("222-222-222", employee.get(Employee_.phoneNumbers)));
......

Complete Example

Entities

@Entity
public class Employee {
  @Id
  @GeneratedValue
  private long id;
  private String name;
  @ManyToMany(cascade = CascadeType.ALL)
  private List<Task> tasks;
  @ElementCollection
  private List<String> phoneNumbers;
  private String primaryPhoneNumber;
    .............
}
@Entity
public class Task {
  @Id
  @GeneratedValue
  private long id;
  @Column(unique = true)
  private String description;
  private String supervisor;
    .............
}

Main class using isMember() and isNotMember()

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

  public static void main(String[] args) {
      try {
          persistEmployees();
          findEmployeeByPhoneNumber();
          //with NOT and using parameter
          findEmployeeByPhoneNumber2();
          //Using isMember of value (phoneNumbers) from the same table (primaryPhoneNumber)
          findEmployeeByMissingPhoneNumber();
          //using another entity instance with MEMBER OF
          findEmployeeByTaskDesc();
      } finally {
          entityManagerFactory.close();
      }
  }

  private static void findEmployeeByPhoneNumber() {
      System.out.println("-- Employees with phone number 222-222-222 --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = criteriaQuery.from(Employee.class);
      criteriaQuery.select(employee)
                   .where(criteriaBuilder.isMember(criteriaBuilder.literal("222-222-222"),
                           employee.get(Employee_.phoneNumbers)));
      TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);
      List<Employee> list = typedQuery.getResultList();
      list.forEach(System.out::println);
      entityManager.close();
  }

  private static void findEmployeeByPhoneNumber2() {
      System.out.println("-- Employees with phone number NOT 222-222-222 --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = criteriaQuery.from(Employee.class);
      criteriaQuery.select(employee)
                   .where(criteriaBuilder.isNotMember("222-222-222",
                           employee.get(Employee_.phoneNumbers)));
      TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);
      List<Employee> list = typedQuery.getResultList();
      list.forEach(System.out::println);
      entityManager.close();
  }

  private static void findEmployeeByMissingPhoneNumber() {
      System.out.println("-- Employees With PhoneNumbers List missing PrimaryPhoneNumber --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = criteriaQuery.from(Employee.class);
      criteriaQuery.select(employee)
                   .where(criteriaBuilder.isNotMember(employee.get(Employee_.primaryPhoneNumber),
                           employee.get(Employee_.phoneNumbers)));
      TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);
      List<Employee> list = typedQuery.getResultList();
      list.forEach(System.out::println);
      entityManager.close();
  }

  private static void findEmployeeByTaskDesc() {
      System.out.println("-- Employees with task 'Designing' --");
      EntityManager entityManager = entityManagerFactory.createEntityManager();
      CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
      //find task by name first
      CriteriaQuery<Task> criteriaQuery = criteriaBuilder.createQuery(Task.class);
      Root<Task> task = criteriaQuery.from(Task.class);
      criteriaQuery.select(task)
                   .where(criteriaBuilder.equal(task.get(Task_.description), "Designing"));
      Task designingTask = entityManager.createQuery(criteriaQuery).getSingleResult();

      //find employees now
      CriteriaQuery<Employee> criteriaQuery2 = criteriaBuilder.createQuery(Employee.class);
      Root<Employee> employee = criteriaQuery2.from(Employee.class);
      criteriaQuery2.select(employee)
                    .where(criteriaBuilder.isMember(designingTask,
                            employee.get(Employee_.tasks)));
      TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery2);
      List<Employee> list = typedQuery.getResultList();
      list.forEach(System.out::println);
      entityManager.close();
  }

  public static void persistEmployees() {
      Task task1 = new Task("Coding", "Denise");
      Task task2 = new Task("Refactoring", "Rose");
      Task task3 = new Task("Designing", "Denise");
      Task task4 = new Task("Documentation", null);

      Employee employee1 = Employee.create("Diana", Arrays.asList("111-111-111", "222-222-222"),
              "111-111-111", task1);
      Employee employee2 = Employee.create("Mike", Arrays.asList("666-666-666", "444-444-444"),
              "888-888-888", task2, task3);
      Employee employee3 = Employee.create("Tim", Arrays.asList("555-555-555", "222-222-222"),
              "222-222-222", task2);
      Employee employee4 = Employee.create("Jack", Arrays.asList("333-333-333"),
              "777-777-777", task4);

      EntityManager em = entityManagerFactory.createEntityManager();
      em.getTransaction().begin();
      em.persist(employee1);
      em.persist(employee2);
      em.persist(employee3);
      em.persist(employee4);
      em.getTransaction().commit();
      em.close();
      System.out.println("-- Employee persisted --");
      System.out.println(employee1);
      System.out.println(employee2);
      System.out.println(employee3);
      System.out.println(employee4);
  }
}
-- Employee persisted --
Employee{id=1, name='Diana', tasks=[Task{id=2, description='Coding', supervisor='Denise'}], phoneNumbers=[111-111-111, 222-222-222], primaryPhoneNumber='111-111-111'}
Employee{id=3, name='Mike', tasks=[Task{id=4, description='Refactoring', supervisor='Rose'}, Task{id=5, description='Designing', supervisor='Denise'}], phoneNumbers=[666-666-666, 444-444-444], primaryPhoneNumber='888-888-888'}
Employee{id=6, name='Tim', tasks=[Task{id=4, description='Refactoring', supervisor='Rose'}], phoneNumbers=[555-555-555, 222-222-222], primaryPhoneNumber='222-222-222'}
Employee{id=7, name='Jack', tasks=[Task{id=8, description='Documentation', supervisor='null'}], phoneNumbers=[333-333-333], primaryPhoneNumber='777-777-777'}
-- Employees with phone number 222-222-222 --
Employee{id=1, name='Diana', tasks=[Task{id=2, description='Coding', supervisor='Denise'}], phoneNumbers=[111-111-111, 222-222-222], primaryPhoneNumber='111-111-111'}
Employee{id=6, name='Tim', tasks=[Task{id=4, description='Refactoring', supervisor='Rose'}], phoneNumbers=[555-555-555, 222-222-222], primaryPhoneNumber='222-222-222'}
-- Employees with phone number NOT 222-222-222 --
Employee{id=3, name='Mike', tasks=[Task{id=4, description='Refactoring', supervisor='Rose'}, Task{id=5, description='Designing', supervisor='Denise'}], phoneNumbers=[666-666-666, 444-444-444], primaryPhoneNumber='888-888-888'}
Employee{id=7, name='Jack', tasks=[Task{id=8, description='Documentation', supervisor='null'}], phoneNumbers=[333-333-333], primaryPhoneNumber='777-777-777'}
-- Employees With PhoneNumbers List missing PrimaryPhoneNumber --
Employee{id=3, name='Mike', tasks=[Task{id=4, description='Refactoring', supervisor='Rose'}, Task{id=5, description='Designing', supervisor='Denise'}], phoneNumbers=[666-666-666, 444-444-444], primaryPhoneNumber='888-888-888'}
Employee{id=7, name='Jack', tasks=[Task{id=8, description='Documentation', supervisor='null'}], phoneNumbers=[333-333-333], primaryPhoneNumber='777-777-777'}
-- Employees with task 'Designing' --
Employee{id=3, name='Mike', tasks=[Task{id=4, description='Refactoring', supervisor='Rose'}, Task{id=5, description='Designing', supervisor='Denise'}], phoneNumbers=[666-666-666, 444-444-444], primaryPhoneNumber='888-888-888'}

Example Project

Dependencies and Technologies Used:

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

JPA Criteria API - isMember() and isNotMember() Examples Select All Download
  • jpa-criteria-api-is-member-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also