Close

JPA - JPQL CASE Expressions With Polymorphic Types using TYPE operator

Following example shows how to use 'CASE' expression with TYPE operator.

Polymorphic Entities

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Entity
@DiscriminatorColumn(name = "EMP_TYPE")
public class Employee {
  @Id
  @GeneratedValue
  private long id;
  private String name;
    .............
}
@Entity
@DiscriminatorValue("F")
public class FullTimeEmployee extends Employee {
  private int annualSalary;
    .............
}
@Entity
@DiscriminatorValue("P")
public class PartTimeEmployee extends Employee {
  private int weeklySalary;
    .............
}
@Entity
@DiscriminatorValue("C")
public class ContractEmployee extends Employee {
  private int hourlyRate;
    .............
}

Using CASE expressions

public class ExampleMain {

  public static void main(String[] args) throws Exception {
      EntityManagerFactory emf =
              Persistence.createEntityManagerFactory("example-unit");
      try {
          persistEntities(emf);
          findAllEmployeesWithTypes(emf);
          findSalaries(emf);
      } finally {
          emf.close();
      }
  }

  private static void persistEntities(EntityManagerFactory emf) throws Exception {
      System.out.println("-- Persisting entities --");
      EntityManager em = emf.createEntityManager();
      em.getTransaction().begin();
      for (Employee employee : createEmployees()) {
          em.persist(employee);
          System.out.println(employee);
      }
      em.getTransaction().commit();
  }

  private static void findAllEmployeesWithTypes(EntityManagerFactory emf) {
      System.out.println("-- finding employees with types --");
      EntityManager em = emf.createEntityManager();
      Query query = em.createQuery("SELECT e.id, e.name, "
              + "CASE TYPE(e)"
              + "WHEN FullTimeEmployee THEN 'FullTime' "
              + "WHEN PartTimeEmployee THEN 'PartTime' "
              + "WHEN ContractEmployee THEN 'Contractor' "
              + "END"
              + " FROM Employee e");
      query.getResultList()
           .forEach((Consumer<Object[]>) o ->
                   System.out.println(Arrays.toString(o)));
      em.close();
  }

  private static void findSalaries(EntityManagerFactory emf) {
      System.out.println("-- finding salaries --");
      EntityManager em = emf.createEntityManager();
      Query query = em.createQuery("SELECT e.id, e.name, "
              + "CASE "
              + "WHEN TYPE(e) = FullTimeEmployee THEN CONCAT(e.annualSalary, ' per annum') "
              + "WHEN TYPE(e) = PartTimeEmployee THEN CONCAT(e.weeklySalary, ' per week') "
              + "WHEN TYPE(e) = ContractEmployee THEN CONCAT(e.hourlyRate, ' per hour') "
              + "END"
              + " FROM Employee e");
      query.getResultList()
           .forEach((Consumer<Object[]>) o ->
              System.out.println(Arrays.toString(o)));
      em.close();
  }


  private static List<Employee> createEmployees() {
      List<Employee> list = new ArrayList<>();
      FullTimeEmployee e = new FullTimeEmployee();
      e.setName("Sara");
      e.setSalary(100000);
      list.add(e);

      e = new FullTimeEmployee();
      e.setName("Mike");
      e.setSalary(90000);
      list.add(e);

      PartTimeEmployee e2 = new PartTimeEmployee();
      e2.setName("Jon");
      e2.setWeeklySalary(900);
      list.add(e2);

      e2 = new PartTimeEmployee();
      e2.setName("Jackie");
      e2.setWeeklySalary(1200);
      list.add(e2);

      ContractEmployee e3 = new ContractEmployee();
      e3.setName("Tom");
      e3.setHourlyRate(60);
      list.add(e3);

      e3 = new ContractEmployee();
      e3.setName("Aly");
      e3.setHourlyRate(90);
      list.add(e3);
      return list;
  }
}
-- Persisting entities --
FullTimeEmployee{id=1, name='Sara', salary=100000}
FullTimeEmployee{id=2, name='Mike', salary=90000}
PartTimeEmployee{id=3, name='Jon'weeklySalary=900}
PartTimeEmployee{id=4, name='Jackie'weeklySalary=1200}
ContractEmployee{id=5, name='Tom', hourlyRate='60'}
ContractEmployee{id=6, name='Aly', hourlyRate='90'}
-- finding employees with types --
[1, Sara, FullTime]
[2, Mike, FullTime]
[3, Jon, PartTime]
[4, Jackie, PartTime]
[5, Tom, Contractor]
[6, Aly, Contractor]
-- finding salaries --
[1, Sara, 100000 per annum]
[2, Mike, 90000 per annum]
[3, Jon, 900 per week]
[4, Jackie, 1200 per week]
[5, Tom, 60 per hour]
[6, Aly, 90 per hour]

Example Project

Dependencies and Technologies Used:

  • h2 1.4.197: H2 Database Engine.
  • hibernate-core 5.2.13.Final: The core O/RM functionality as provided by Hibernate.
    Implements javax.persistence:javax.persistence-api version 2.1
  • JDK 1.8
  • Maven 3.5.4

jpql-case-expressions-with-polymorphic-types Select All Download
  • jpql-case-expressions-with-polymorphic-types
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also