Search code examples
javahibernatecriteria

Hibernate criteria - get a list of associated entities, not the parent ones


I've got two entities with unidirectional @OneToMany mapping:

@Entity
@Table(name = "table1")
public class A {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer pk;

    String name;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "a_pk", nullable = false)
    @Where(clause =  "is_deleted = 0")
    List<B> children;
}

@Entity
@Table(name = "table2")
public class B {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer pk;

    String content;

    @Column(name = "is_deleted",nullable=false)
    @NotNull
    boolean deleted = false;
}

I want to obtain a list of all B entities, which are children of A entities matching a restriction.

Criteria c = session.createCriteria(A.class)
    .add(Restriction.like("name", "Test%"))
    .createAlias("children","b");
???

And this is where I'm stuck: c.list() will return me a list of A objects. I don't care about A, I want B. How can I do it with Hibernate criteria/projections? If it matters, I use Hibernate 4.2.12

In this simplified case it would make sense to just fetch eagerly; in the real case there's a chain of four OneToMany unidirectional associations, and I want to get all (or better yet, SOME) children all the way down the tree knowing the root id; but I don't want to load all the intermediate stuff (it's not needed, and even if join-fetching four tables would work it's plain gross). Also, simply getting the root and following down the lazy associations is a clear example of N+1 problem escalated.

As a side question, does Hibernate criteria satisfy entity/property @Where restrictions?


Solution

  • So, yeah, I went with using HQL in the end. Nothing special.

    List<B> bList = session.createQuery(
            "select b from A as a join a.children as b where a.name like 'Test%'"
            ).list();