S
S
Sland Show2018-12-26 12:41:52
Java
Sland Show, 2018-12-26 12:41:52

How to do double join in criteria api?

I have the following picture.

There are 3 tables: 5c234b476d080426225192.jpeg

And so I also have a RequestDTO, which is fed into the endpoint's parameters to provide a search from the database by criteria.

This is what the DTO itself looks like:

@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 and ontSerialNumber are in two different tables.

To get the ontId, I do the following JOIN through the criteria:
// 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));
                    }
            );


But in order for me to pull out ontSerialNumber , I have to go into table B, and join C from this table B.

How can I do this if the current criteria looks like this:
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]));
        };
    }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sland Show, 2018-12-26
@SlandShow

I decided.
Joynu first A <- B, thenB <- 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));
                    }
            );

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question