Reputation: 951
How can I build a DTO using JPA Criteria builder with a join on tables linked by a one-to-many relation?
In the documentation, there is no example using both a wrapper and join cases.
For instance :
EntityA {
String name;
@OneToMany
Set<EntityB> items;
...
}
Wrapper {
name;
Set<EntityB> items;
}
Upvotes: 1
Views: 694
Reputation: 11551
If I remember right, you can't. Projection doesn't handle joins. Perhaps you might want to query a list of EntityB
instead of an EntityA
with items
and pass the items list to a Dto object that takes the parent entity and its list. Not what you want, to be sure, but should get the job done. So, by example:
@Entity
public class EntityA {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy="a")
private Set<EntityB> bs;
@Entity
public class EntityB {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private EntityA a;
public class WrapperDto {
private EntityA a;
private List<EntityB> bs;
public WrapperDto(EntityA a, List<EntityB> bs) {
this.a = a;
this.bs = bs;
}
and to use it:
tx.begin();
EntityA a = new EntityA();
EntityB b1 = new EntityB();
EntityB b2 = new EntityB();
b1.setA(a);
b2.setA(a);
em.persist(a);
em.persist(b1);
em.persist(b2);
tx.commit();
em.clear();
// projection with join fetch doesn't work.
// em.createQuery("select new dto.WrapperDto( a, bs ) from EntityA a left outer join fetch a.bs bs where a.id = 1", WrapperDto.class).getResultList();
// a possible solution
EntityA aFound = em.find(EntityA.class, 1L);
List<EntityB> bs = em.createQuery("select b from EntityB b where b.a = :a", EntityB.class).setParameter("a", aFound).getResultList();
WrapperDto dto = new WrapperDto(aFound, bs);
Upvotes: 1