JPA Criteria API, возвращает результаты, если объединенная таблица содержит как минимум две строки, которые отличаются одновременно типом и датой - PullRequest
0 голосов
/ 08 ноября 2019

Я дал две таблицы Order и Route, как показано ниже:

public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false, updatable = false)
    private Long id;


    @NotNull
    @JsonIgnore
    @Column(name = "routes")
    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List<Route> routes;

}

public class Route {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false)
    private Long id;

    @Column(name = "date")
    private LocalDate date;

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(name = "type")
    private LoadingType type;
}

Я должен выбрать все Заказы, используя Criteria API, где есть хотя бы один случай обоих:

 Route{
     type = LOADING;
     date = "2019-11-11";
 }

 Route{
     type = UNLOADING;
     date = "2019-11-12";
 }

То, что я сейчас сделал, это:

    private List<Predicate> preparePredicatesForRoutes(OrderSearchFilter filter,
                                                       CriteriaBuilder builder,
                                                       Join<Order, Route> routeJoin) {
        List<Predicate> predicates = new ArrayList<>();

        if (filter.getUnloadingDate() != null) {
            predicates.add(builder.equal(routeJoin.get("date"), filter.getUnloadingDate()));
            predicates.add(builder.equal(routeJoin.get("type"), LoadingType.UNLOADING));
        }
        if (filter.getLoadingDate() != null) {
            predicates.add(builder.equal(routeJoin.get("date"), filter.getLoadingDate()));
            predicates.add(builder.equal(routeJoin.get("type"), LoadingType.LOADING));
        }
        return predicates;
    }

Основная проблема заключается в том, что он будет работать идеально, если одновременно присутствует только один из двух фильтров. Если оба будут добавлены, он просто создаст запрос, который будет ожидать, что все строки в маршрутах будут соответствовать исключающим критериям: все они должны быть также ЗАГРУЗИТЬ с датой "2019-11-11" и в то же время РАЗГРУЗИТЬ тип с датой "2019-11-12" . Я хочу получить все заказы, имеющие как минимум 1 Маршрут ЗАГРУЗКИ и «2019-11-11» и хотя бы один маршрут РАЗГРУЗКИ и «2019-11-12». Что я должен делать?

...