Обертка построителя критериев JPA с объединением - PullRequest
0 голосов
/ 08 ноября 2018

Как я могу построить DTO, используя построитель JPA Criteria с объединением таблиц, связанных отношением один-ко-многим?

В документации нет примеров использования оболочек и случаев соединения.

JPA Doc

Например:

EntityA {
   String name;

   @OneToMany
   Set<EntityB> items;

   ...
}


Wrapper {
   name;
   Set<EntityB> items;
}

1 Ответ

0 голосов
/ 09 ноября 2018

Если я правильно помню, вы не можете. Проекция не обрабатывает соединения. Возможно, вы захотите запросить список EntityB вместо EntityA с items и передать список элементов объекту Dto, который принимает родительский объект и его список. Не то, что вы хотите, конечно, но должны сделать работу. Итак, к примеру:

@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;
    }

и использовать его:

    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);
...