SlandShow
@SlandShow
70% of my body is made of movies.

Как сделать двойной join в criteria api?

У меня есть следующая картина.

Имеется 3 таблицы: 5c234b476d080426225192.jpeg

И так-же у меня есть RequestDTO, которая подаётся в параметры endpoint'а, чтобы обеспечить поиск из Бд по критериям.

Так выглядит сама DTO:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class RequestAssuranceAccessLine {

    @Pattern(regexp =  LINE_ID)
    private String lineId;

    @Min(0) @Max(31)
    private Integer ontId;

    private Technology technology;

    @Size(max = 50)
    private String ontSerialNumber;

    @ApiParam(allowEmptyValue = true)
    public RequestAssuranceAccessLine setLineId(String lineId) {
        this.lineId = lineId;
        return this;
    }

    @ApiParam(allowEmptyValue = true)
    public RequestAssuranceAccessLine setOntId(Integer ontId) {
        this.ontId = ontId;
        return this;
    }

    @ApiParam(allowEmptyValue = true)
    public RequestAssuranceAccessLine setTechnology(Technology technology) {
        this.technology = technology;
        return this;
    }

    @ApiParam(allowEmptyValue = true)
    public RequestAssuranceAccessLine setOntSerialNumber(String ontSerialNumber) {
        this.ontSerialNumber = ontSerialNumber;
        return this;
    }

}


ontId и ontSerialNumber находятся в двух разных таблицах.

Чтобы достать ontId, я делаю следующий JOIN через критерию:
// Join and predicate ontId from Default NeProfile
            Optional.ofNullable(requestAssuranceAccessLine.getOntId()).ifPresent(ontId -> {
                        Join<DefaultNeProfile, AccessLine> joinedDefaultNeProfile = root.join("defaultNeProfile");
                        predicates.add(criteriaBuilder.equal(joinedDefaultNeProfile.get("ontId"), ontId));
                    }
            );


Но чтобы мне вытащить ontSerialNumber, придётся лезть в таблицу B, и из этой таблицы B джойнить C.

Как же мне это сделать, если текущий criteria выглядит так:
public static Specification<AccessLine> criteriaForAccessLine(RequestAssuranceAccessLine requestAssuranceAccessLine) {
        return (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            // Predicate lineId
            Optional.ofNullable(requestAssuranceAccessLine.getLineId()).ifPresent(lineId -> predicates.add(criteriaBuilder.equal(root.get("lineId"), lineId)));

            // Join and predicate ontId from Default NeProfile
            Optional.ofNullable(requestAssuranceAccessLine.getOntId()).ifPresent(ontId -> {
                        Join<DefaultNeProfile, AccessLine> joinedDefaultNeProfile = root.join("defaultNeProfile");
                        predicates.add(criteriaBuilder.equal(joinedDefaultNeProfile.get("ontId"), ontId));
                    }
            );

            // Predicate technology
            Optional.ofNullable(requestAssuranceAccessLine.getTechnology()).ifPresent(technology -> predicates.add(criteriaBuilder.equal(root.get("technology"), technology)));
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
    }
  • Вопрос задан
  • 47 просмотров
Решения вопроса 1
SlandShow
@SlandShow Автор вопроса
70% of my body is made of movies.
решил.

Сначала джойню A <- B, поотом B <- C

// Join and predicate ontSerialNumber from Subscriber NeProfile 
            Optional.ofNullable(requestAssuranceAccessLine.getOntSerialNumber()).ifPresent(ontSerialNumber -> {
                        Join<DefaultNeProfile, AccessLine> joinedDefaultNeProfile = root.join("defaultNeProfile");
                        Join<SubscriberNeProfile, DefaultNeProfile> joinedSubscriberNeProfile = joinedDefaultNeProfile.join("subscriberNeProfile");
                        predicates.add(criteriaBuilder.equal(joinedSubscriberNeProfile.get("ontSerialNumber"), ontSerialNumber));
                    }
            );
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
ГК «ОПТИМАЛ» Тверь
До 150 000 руб.
МойСклад Москва
от 120 000 до 170 000 руб.
TecForce Санкт-Петербург
от 120 000 до 220 000 руб.