java springframework.data.jpa создает одно и то же соединение дважды, используя JpaSpecificationExecutor - PullRequest
0 голосов
/ 11 февраля 2020

Я использую JpaSpecificationExecutor, поэтому я создаю свой sql динамически, используя спецификацию Api из org.springframework.data.jpa.domain.Specification, и проблема в том, что он генерирует одно и то же соединение дважды, что снижает производительность, здесь это код:

метод вызова:

private Specification<EntityA> toSpecEntityBAndEntityC(boolean withEntityBAndEntityC, Specification<EntityA> specs) {
        if (withEntityBAndEntityC) {
            specs = Specification.where(specs).and(EntityASpecs.withEntityB());
            specs = Specification.where(specs).and(EntityASpecs.withEntityC());
        }
        return specs;
    }

вот класс EntityASpecs

public interface EntityASpecs{
static Specification<EntityA> withEntityB() {
        return (root, query, builder) -> {
            if (!isCountQuery(query)) {
                root.fetch(EntityA_.EntityB);
            } else {
                root.join(EntityA_.EntityB,JoinType.INNER);
            }
            return null;
        };
    }



    static Specification<EntityA> withEntityC() {
        return (root, query, builder) -> {
            if (!isCountQuery(query)) {
                root.fetch(EntityA_.EntityC);
            } else {
                root.join(EntityA_.EntityC,JoinType.INNER);
            }
            return null;
        };
    }
}

вот сущности:

@Data
@Entity
public class EntityA{

    @Id
    @GeneratedValue(generator = "seq_entityB")
    @SequenceGenerator(name = "seq_entityB", sequenceName = "SEQ_entityB", allocationSize = 1)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private EntityB entityB;

@ManyToOne(fetch = FetchType.LAZY)
    private EntityC entityC ;
    }

генерирует этот запрос

  select *
from (select entityA0_.id                    as id1_4_0_,
             entityC2_.filedOne                  as filedOne1_3_1_,
             entityB3_.filedTwo                       as filedTwo1_1_2_,
             entityA0_.filedFive_id       as filedFive_id7_4_0_,
             entityA0_.entityB_filedTwo             as entityB_filedTwo8_4_0_,
             entityA0_.DATE_TRAITEMENT       as DATE_TRAITEMENT2_4_0_,
             entityA0_.filedFour               as filedFour3_4_0_,
             entityA0_.entityC_filedOne        as entityC_filedOne9_4_0_,
             entityA0_.filedSix                  as filedSix4_4_0_,
             entityA0_.filedSeven                as filedSeven5_4_0_,
             entityA0_.TEMPS_REPONSE         as TEMPS_REPONSE6_4_0_,
             entityC2_.NB_MOYEN_TRAITEMENTS as NB_MOYEN_TRAITEMEN2_3_1_,
             entityC2_.filedSeven               as filedSeven3_3_1_,
             entityC2_.filedSixteen    as filedSixteen4_3_1_,
             entityB3_.filedFifteen        as DATE_TRAITEMENT_SA2_1_2_,
             entityB3_.filedEight                as filedEight11_1_2_,
             entityB3_.filedTen               as filedTen3_1_2_,
             entityB3_.filedNine                    as filedNine4_1_2_,
             entityB3_.filedFourteen                    as filedFourteen5_1_2_,
             entityB3_.filedThirteen                        as filedThirteen6_1_2_,
             entityB3_.NUMERO_AUTORISATION        as NUMERO_AUTORISATIO7_1_2_,
             entityB3_.filedEleven                 as filedEleven8_1_2_,
             entityB3_.filedSeven                     as filedSeven9_1_2_,
             entityB3_.filedTwelve                   as filedTwelve10_1_2_
      from entityA entityA0_
             inner join entityB entityB1_ on entityA0_.entityB_filedTwo = entityB1_.filedTwo
             inner join entityC entityC2_ on entityA0_.entityC_filedOne = entityC2_.filedOne
             **inner join entityB entityB3_ on entityA0_.entityB_filedTwo = entityB3_.filedTwo**
      where entityA0_.filedSix = 'Value'
        and (entityB1_.filedFifteen between TO_DATE('2018-11-08 14:00:00', 'YYYY-MM-DD HH24:MI:SS') and TO_DATE('2018-11-08 15:00:00', 'YYYY-MM-DD HH24:MI:SS'))
      order by entityA0_.DATE_TRAITEMENT desc)
;

NB:

повторяющееся соединение между двумя звездами

**inner join entityB entityB3_ on entityA0_.entityB_filedTwo = entityB3_.filedTwo**
...