Reputation: 616
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?
Upvotes: 2
Views: 4025
Reputation: 89
You can use projection to get list of "b". Like this :
Criteria c = session.createCriteria(A.class)
.add(Restriction.like("name", "Test%"))
.createAlias("children","b").setProjection(Projections.property("b"));
after this when you try to get results using c.list()
it will return a list of B.
I hope this helps!!
Upvotes: 2
Reputation: 616
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();
Upvotes: 0