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