Search code examples
javahibernatehierarchyhibernate-criteria

Table per Class hierarchy - get only Superclass with Criteria API, discriminator not working?


I have Table per Class hierarchy with 3 classes, Academy:

@Entity
@Table(name = "academy")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(
        name="hibernate_hierarchy_discriminator",
        discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue(value="ACADEMY")
public class Academy {
//
}

Class Institute, which extends Academy:

@Entity
@Table(name = "institute")
@DiscriminatorValue(value="INSTITUTE")
public class Institute extends Academy{
//
}

And class Department, which extends Instutute:

@Entity
@Table(name = "department")
@DiscriminatorValue(value="DEPARTMENT")
public class Department extends Institute{
//
}

And when I save particular entities, it looks OK - for example I see discriminator column. But when I save one Academy, one Institute and one Department - and I try to get only Academies, I got 3 elements but I expect only one - list contains not only Academy but also Institute and Department. I created a unit test which shows what I mean:

@Test
@Transactional
public void test_WhenOneAcademyIsSaved_OneAcademyShouldBeRead() throws Exception {
    //tables are empty before test

    final Academy academy = new Academy("Michigan", "Main street");
    getCurrentSession().save(academy);
    final Institute institute = new Institute("Michigan", "Main street", "IT", "C", academy);
    getCurrentSession().save(institute);
    getCurrentSession().save(new Department("Michigan", "Main street", "IT", "C", "333 333 333", "Programming", institute));

    List<Academy> academies = (List<Academy>)getCurrentSession()
        .createCriteria(Academy.class)
        .list();
    assertEquals(1, academies.size()); //size is 3
}

(This is also tree structure and Academy has a list of Instututes, and Institute has a list of Departments, bu I think it does not matter in my problem). I thought that discriminator column cares about distinguishing between different class instances and if I create Criteria for Academy, I will get only Academies. Is there a solution to get only base class instances with Criteria API when Table per Class hierarchy is used?


Solution

  • I resolved it in this way: Because I need to distinguish between parent entity Academy and child entity Institute I decided to remove explicite inheritance. Instead, I create BaseAcademy class from which Academy inherits and BaseInstitute from which Institute inherits. Now, there is no "Hibernate" inheritance, but BaseInstitute class inherits from BaseAcademy. I don't know if it is good solution, but at this moment everything works.