Критерий API - 2 пути и слишком много соединений - PullRequest
0 голосов
/ 17 июня 2019

Я хотел бы создать запрос с 2 условиями WHERE, используя Criteria API. У меня есть объект A, который имеет вложенные поля (@OneToMany и т. Д.). Я хотел бы создать выбор с условиями WHERE, как:

entity A.fieldB.fieldC.id = X and A.fieldB.fieldD.id = Y



 public <T> List<T> getEntityWithParams(Map<Field, Object> params, Reportable<T> reportable) {
            CriteriaBuilder builder = em.getCriteriaBuilder();
            CriteriaQuery<T> query = builder.createQuery(reportable.getReportEntityClass());
            Root<T> from = query.from(reportable.getReportEntityClass());
            Predicate conditions = builder.conjunction();

            Path<Object> path = from.join("activityCategories")
                    .get("processActivity")
                    .get("personalData")
                    .get("company")
                    .get("id");

            Path<Object> path2 = from.join("activityCategories")
                    .get("processActivity")
                    .get("personalData")
                    .get("administrator")
                    .get("id");

    //      builder.and(conjunction, builder.equal(path, value), builder.equal(path2, 4)))

            conditions = builder.and(builder.equal(path, 1), builder.equal(path2, 4));


            List<T> typedQuery = em.createQuery(query
                            .select(from)
                            .where(conditions)
                            .distinct(true)).getResultList();

Когда я использую 2 пути, Hibernate создает JOIN в два раза больше:

select
        distinct processing0_.id as id1_51_,
        processing0_.data_wpr as data_wpr2_51_,
        processing0_.opr as opr3_51_,
        processing0_.aktywna as aktywna4_51_,
        processing0_.id_spolka as id_spolk7_51_,
        processing0_.nazwa as nazwa5_51_,
        processing0_.nazwa_kategorii_podpowierzenia_przetwarzania as nazwa_ka6_51_ 
    from
        odo.odo_kategoria_czynnosci_przetwarzania processing0_ 
    inner join
        odo.odo_czynnosc_kategoria activityca1_ 
            on processing0_.id=activityca1_.id_kategoria_czynnosci 
    inner join
        odo.odo_czynnosc_kategoria activityca2_ 
            on processing0_.id=activityca2_.id_kategoria_czynnosci cross 
    join
        odo.odo_czynnosc_przetwarzania processing3_ cross 
    join
        odo.odo_zbior personalda4_ cross 
    join
        odo.odo_czynnosc_przetwarzania processing5_ cross 
    join
        odo.odo_zbior personalda6_ 
    where
        activityca1_.id_czynnosc=processing3_.id 
        and processing3_.id_zbior=personalda4_.id 
        and activityca2_.id_czynnosc=processing5_.id 
        and processing5_.id_zbior=personalda6_.id 
        and personalda4_.id_zbior_spolka=1 
        and personalda6_.id_zbior_administrator=4

следовательно, результаты неверны. Дополнительно используются крестовые соединения. У вас есть идеи, как подготовить запрос, подобный этому:

select
        distinct processing0_.id as id1_51_,
        processing0_.data_wpr as data_wpr2_51_,
        processing0_.opr as opr3_51_,
        processing0_.aktywna as aktywna4_51_,
        processing0_.id_spolka as id_spolk7_51_,
        processing0_.nazwa as nazwa5_51_,
        processing0_.nazwa_kategorii_podpowierzenia_przetwarzania as nazwa_ka6_51_ 
    from
        odo.odo_kategoria_czynnosci_przetwarzania processing0_ 
    inner join
        odo.odo_czynnosc_kategoria activityca1_ 
            on processing0_.id=activityca1_.id_kategoria_czynnosci 
    inner join

    join
        odo.odo_zbior personalda4_ on personalda4_ = processing0_.id_zbior

    where
         personalda4_.id_zbior_spolka=1 
        and personalda4_.id_zbior_administrator=4
...