Search code examples
javahibernatehql

Ascend HQL inheritance hierarchy from subclass to superclass


Given three entities A, B and C where B extends A such as :

@Entity
@Table(name = "a")
public class A {
    private C c;
    //omitted source code

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "c_id", nullable = false)
    public C getC() {
       return c;
    }
    public void setC(C c){
       this.c=c;
    }
}

@Entity
@Table(name = "b")
public class B extends A {
    private Integer id;
    //omitted source code
}

@Entity
@Table(name = "c")
public class C {
    private Integer id;
    private String status;
    //omitted source code
}

How can I convert to following native SQL to HQL :

select b.* from b b_
inner join a a_ on a_.id=b_.id
inner join c c_ on a_.c_id=c_.id
where c_.status='ACCEPTED';

I tried the following : select b from B b join b.c c where c.status = 'ACCEPTED' however I get this exception : org.hibernate.QueryException: could not resolve property: c of: B. I thought Hibernate would resolve the superclass fields at runtime.

What I am trying to achieve here is to ascend the inheritance hierarchy starting exactly from from B and read the superclass A inner fields, in particular c. I wonder if this is doable in hibernate. Otherwise any alternative solution will be more than welcome.


Solution

  • Change the visibility of the C instance variable inside A:

    public class A {
        protected C c;
        //....
    

    protected ensures the children of A (and also other members in the same package where A is located) to be able to directly access c, as it becomes an inherited variable.

    This way, c is visible from any B instance, leading to bInstance.c being valid. As a result, hibernate would identify select b from B b join b.c c as a valid command.