Я дал две таблицы 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». Что я должен делать?