Привет, я хотел бы создать запрос JPA с параметрами, используя QueryDSL, код выглядит как
private static JPAQuery<Tuple> projectionQuery(JPAQuery<?> query, QCoupon qCoupon, QCouponApplication qCouponApplication) {
return query.select(
qCoupon.id,
qCoupon.code,
qCoupon.status,
qCoupon.amount,
qCoupon.benefitType,
qCoupon.maxDiscountPerApplication,
qCoupon.additionalMonth,
qCouponApplication.count().as("usedQuota"),
qCoupon.globalQuota,
qCoupon.basePriceOnly
);
}
public GetCouponsResponseDTO getCouponsRewrited(String code, ZonedDateTime startCreatedDate, ZonedDateTime endCreatedDate, CouponStatus status, Integer pageNumber, Integer pageSize) {
QCoupon qCoupon = QCoupon.coupon;
QCouponApplication qCouponApplication = QCouponApplication.couponApplication;
PageRequest pageRequest = new PageRequest(pageNumber, pageSize);
JPAQuery<?> query =
projectionQuery(new JPAQuery<>(), qCoupon, qCouponApplication)
.from(qCoupon).leftJoin(qCoupon.applications, qCouponApplication)
.groupBy(qCoupon)
.orderBy(new OrderSpecifier<>(Order.DESC, qCoupon.createdAt));
if (StringUtils.isNotBlank(code)) {
ParamExpression<String> codeParam = new ParamExpressionImpl<>(String.class);
query = query.where(qCoupon.code.likeIgnoreCase(codeParam)).set(codeParam, '%' + code + '%');
}
if (Objects.nonNull(startCreatedDate)) {
ParamExpression<ZonedDateTime> createdAtParam = new ParamExpressionImpl<>(ZonedDateTime.class);
query = query.where(qCoupon.createdAt.goe(createdAtParam)).set(createdAtParam, startCreatedDate);
}
if (Objects.nonNull(endCreatedDate)) {
ParamExpression<ZonedDateTime> endedAtParam = new ParamExpressionImpl<>(ZonedDateTime.class);
query = query.where(qCoupon.createdAt.loe(endedAtParam)).set(endedAtParam, endCreatedDate);
}
......
final String queryString = query.toString();
final TypedQuery<Object[]> typedQuery = entityManager.createQuery(queryString, Object[].class)
.setFirstResult(pageRequest.getOffset())
.setMaxResults(pageRequest.getPageSize());
for (Map.Entry<ParamExpression<?>, Object> paramExpressionObjectEntry : query.getMetadata().getParams().entrySet()) {
ParamExpression<?> paramExpression = paramExpressionObjectEntry.getKey();
typedQuery.setParameter(paramExpression.getName(), paramExpressionObjectEntry.getValue());
}
List<Object[]> queryResult = typedQuery
.getResultList();
Проблема в том, что переменная queryString
содержит неназванный параметр, например where lower(coupon.code) like lower(?1)
, а не как и ожидалось с именованным параметром, который начинается с :
. Я попытался использовать имя, добавив второй аргумент конструктора в ParamExpressionImpl
как new ParamExpressionImpl<>(String.class, qCoupon.code.getMetadata().getName())
, это просто то же самое.
В результате он возвращает сообщение об исключении Parameter with that name [code] did not exist
. Как правильно использовать QueryDSL ParamExpression
в строке typedQuery.setParameter(...)
?