Я использую 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**