Я использую базу данных JPA HIBERNATE H2 для своего проекта.
В настоящее время я пытаюсь создать предикат с необязательными частичными предикатами, все работало нормально, пока мне не пришлось создавать сложные запросы.
Я бы хотел отфильтровать мои продукты по тем, у которых есть компонент композиции, чье количество по умолчанию меньше его максимального количества
Я написал такую функцию:
private BooleanExpression getBooleanPredicateComposition(ListPath<Product.Composition.Component, QProduct_Composition_Component> component, QProduct_Composition_Component qpath, Boolean params) {
if(null == params) {
return null;
}
BooleanExpression be = qpath.defaultQuantity.lt(qpath.maxQuantity);
return (params ? be : component.size().gt(0).not());
}
В результате этого выполняется следующий sql:
select
1
from
product$composition product_co3_
inner join
product$composition_component component4_
on product_co3_.composition_id=component4_.product$composition_composition_id
inner join
product$composition_component component5_
on product_co3_.composition_id=component5_.product$composition_composition_id
where
product_co3_.composition_id=product0_.composition_composition_id
and product_co3_.composition_id=product0_.composition_composition_id
and component4_.default_quantity<component5_.max_quantity
Но я хочу sql, где component4_default_quantity связан со своим собственным max_quantity, а не с другой объединенной таблицей, как в настоящее время.
Я точно не эксперт по SQL, на самом деле у меня очень мало опыта с этим, но я думаю, что это должно быть примерно так:
select
1
from
product$composition product_co3_
inner join
product$composition_component component4_
on product_co3_.composition_id=component4_.product$composition_composition_id
where
product_co3_.composition_id=product0_.composition_composition_id
and product_co3_.composition_id=product0_.composition_composition_id
and component4_.default_quantity<component4_.max_quantity
Так как мне его кодировать?
Я испробовал много разных техник, таких как создание нового JPAExpression или обращение к базовому классу QProduct_Composition_Component.component, но ни один из них, похоже, не работает для меня ..
Заранее спасибо!
Обновление:
Остальной код, откуда я вызываю эту функцию
public Predicate getPredicate(ComplexProduct complexProduct) {
return new BooleanBuilder()
.and(PRODUCT.country.eq(complexProduct.getCountry()))
.and(PRODUCT.storeId.eq(complexProduct.getStore()))
.and(getPartialPredicate(complexProduct).build());
}
private WhereClauseBuilder getPartialPredicate(ComplexProduct complexProduct) {
WhereClauseBuilder whereClauseBuilder = new WhereClauseBuilder()
.optionalAnd(PRODUCT.onOutage::eq,complexProduct.getOnOutage())
.optionalAnd(getBooleanPredicateZeroPriced(PRODUCT.priceList.priceTag.pricing.any().price,complexProduct.getZeroPriced(), complexProduct.getNullPriceAllowed()))
.optionalAnd(getBooleanPredicateSalable(PRODUCT.salable, complexProduct.getSalable()))
.optionalAnd(getBooleanPredicateIsActive(PRODUCT.isActive, complexProduct.getIsActive()))
.optionalAnd(getBooleanPredicateHasPromotionTimeRestriction(PRODUCT.promotion.timeRestrictions, complexProduct.getHasPromotionTimeRestriction()))
.optionalAnd(getBooleanPredicateString(PRODUCT.grillGroup, complexProduct.getGrillGroup()))
.optionalAnd(getBooleanPredicateExistsAndHasElement(PRODUCT.canAdds.component, complexProduct.getGrilledCanAdd()))
.optionalAnd(getBooleanPredicateExistsAndHasElement(PRODUCT.comments.component, complexProduct.getGrilledComment()))
.optionalAnd(getBooleanPredicateExistsAndHasElement(PRODUCT.choices.component, complexProduct.getGrilledChoice()))
.optionalAnd(getBooleanPredicateComposition(PRODUCT.composition.component, PRODUCT.composition.component.any(), complexProduct.getCompositionNeeded()))
.optionalAnd(getBooleanPredicateAvailability(PRODUCT, complexProduct.getTime(), complexProduct.getTime(), complexProduct.getDayName(), complexProduct.getAvailableAt()))
.optionalAnd(getBooleanPredicateCustomParameter(PRODUCT.customParameters, "nutritionalInfoEnergy",complexProduct.getNutritionalInfoEnergy()));
if(complexProduct.getDistributions() != null) {
addDistributionFilters(whereClauseBuilder, complexProduct.getDistributions().stream().map(distribution -> distribution.name()).collect(Collectors.toList()));
}
WhereClauseBuilder partialWhere = null;
if(complexProduct.getType() != null) {
if(complexProduct.getType() != null) {
if (partialWhere == null) {
partialWhere = new WhereClauseBuilder();
}
partialWhere = partialWhere.optionalOr(PRODUCT.productClass::eq, complexProduct.getType().getName());
}
}
if(partialWhere != null) {
whereClauseBuilder.optionalAnd(partialWhere.build());
}
return whereClauseBuilder;
}