Hi, I'd like to create JPA query with parameters using QueryDSL, the code is like
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();
The problem is the queryString
variable contains unnamed parameter like where lower(coupon.code) like lower(?1)
not as expected with named parameter that starts with :
. I've tried using name, adding second constructor argument in ParamExpressionImpl
like new ParamExpressionImpl<>(String.class, qCoupon.code.getMetadata().getName())
it's just same.
As a result it returns with exception message Parameter with that name [code] did not exist
. How's the correct use of QueryDSL's ParamExpression
on the typedQuery.setParameter(...)
line?
Instead of ParamExpressionImpl
you should use com.querydsl.core.types.dsl.Param
, which also takes a String argument which will be the name of the parameter ( :parameter
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.