我正在尝试使用标准生成器动态实现此本机查询
@Query(nativeQuery = true, value =
"""
SELECT * FROM unit_register
WHERE unit_nr IN (
SELECT DISTINCT(unit_nr)
FROM local_area_register
WHERE (service_code = :service_code or :service_code is null)
AND (country_code = :country_code or :country_code is null)
AND (postal_code = :postal_code or :postal_code is null)
AND return_code IN ('F', 'U')
AND start_date <= CURRENT_DATE
AND COALESCE(end_date, CURRENT_DATE) >= CURRENT_DATE )
""")
List<UnitRegister> getUnitCodeDetails(@Param("service_code") String serviceCode,
@Param("country_code") String countryCode,
@Param("postal_code") String postalCode);
这是我的实现
public List<UnitRegister> findUnitRegister(String serviceCode, String countryCode, String postalCode) {
return unitRegisterRepository.findAll((Specification<UnitRegister>) (Root<UnitRegister> root,
CriteriaQuery<?> criteriaQuery,
CriteriaBuilder criteriaBuilder) -> {
Subquery<LocalAreaRegister> subQuery = criteriaQuery.subquery(LocalAreaRegister.class);
Root<LocalAreaRegister> subRoot = criteriaQuery.from(LocalAreaRegister.class);
List<Predicate> predicates = new ArrayList<>();
List<Predicate> subPredicates = new ArrayList<>();
var p = criteriaBuilder.conjunction();
if (isNotBlank(serviceCode)) {
subPredicates.add(criteriaBuilder.equal(subRoot.get("id").get("serviceCode"), serviceCode));
}
if (isNotBlank(countryCode)) {
subPredicates.add(criteriaBuilder.equal(subRoot.get("id").get("countryCode"), countryCode));
}
if (isNotBlank(postalCode)) {
subPredicates.add(criteriaBuilder.equal(subRoot.get("id").get("postalCode"), postalCode));
}
CriteriaBuilder.Coalesce<LocalDate> coalesce = criteriaBuilder.coalesce();
coalesce.value(subRoot.get("endDate"));
coalesce.value(LocalDate.now());
subPredicates.add(criteriaBuilder.in(subRoot.get("id").get("returnCode")).value(RETURN_CODES_F_U));
subPredicates.add(criteriaBuilder.lessThanOrEqualTo(subRoot.get("startDate"), LocalDate.now()));
subPredicates.add(criteriaBuilder.greaterThanOrEqualTo(coalesce, LocalDate.now()));
System.out.println("******" + subPredicates.size());
subQuery.select(subRoot.get("id").get("unitNR")).distinct(true).where(subPredicates.toArray(new Predicate[]{}));
return criteriaBuilder.in(root.get("unitNr")).value(subQuery);
});
}
但它失败并显示以下错误消息:
非预期令牌:在第1行附近,第230列[从no.posten.ph. unit.domain.Unit中选择GeneratedAlias0注册为GeneratedAlias0,no.posten.ph.Unit.domain.LocalArea注册为GeneratedAlias1 where atedAlias0.unitNr in(从何处选择不同的generatedAlias1.id.unitNR(generatedAlias1.id.serviceCode=:Param0)和(generatedAlias1.id.国家代码=:Param1)和(generatedAlias1.id.postalCode=:Param2)和(generatedAlias1.id.returCode in(:Param3))和(GeneratedAlias1.start Date
应用程序//org. hibernate.内部.AbstractSharedSession合同.createQuery(AbstractSharedSessionContract.java:748)…127更多
为了简单地理解错误:
[select generatedAlias0 from no.posten.ph.unit.domain.UnitRegister as generatedAlias0, no.posten.ph.unit.domain.LocalAreaRegister as generatedAlias1 where generatedAlias0.unitNr in (select distinct generatedAlias1.id.unitNR from **where** ( generatedAlias1.id.serviceCode=:param0 ) and ( generatedAlias1.id.countryCode=:param1 ) and ( generatedAlias1.id.postalCode=:param2 ) and ( generatedAlias1.id.returnCode in (:param3) ) and ( generatedAlias1.startDate<=:param4 ) and ( coalesce(generatedAlias1.endDate, :param5)>=:param6 ))]
这是正在生成的查询,在“where”之前没有表/实体名称,并且在where子句中只添加了1个谓词,尽管有6个谓词
您的代码将根添加到外部查询
Root<LocalAreaRegister> subRoot = criteriaQuery.from(LocalAreaRegister.class);
当您想将其添加到subQuery
时,即
Root<LocalAreaRegister> subRoot = subQuery.from(LocalAreaRegister.class);