Close

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

[Last Updated: 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