Spring 在 IN 查询中使用 spel 的数据 JPA @Query
Spring Data JPA @Query with spel in a IN query
我在 Spring Data JPA 上工作,我有一个实现 JpaRepository 的存储库接口。
我已经编写了这个完美运行的查询:
@Query ("FROM Person p " +
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code = :#{#code}")
Person findByContractAndRelatedContractRole(@Param ("contract") Contract contract, @Param ("code") String code);
现在我想写另一个可以在多个代码中找到的查询,所以我写了这个查询:
@Query ("FROM Person p " +
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code IN (:#{#codes})")
List<Person> findByContractAndRelatedContractRoles(@Param ("contract") Contract contract, @Param ("codes") String... codes);
但是当我启动我的应用程序时出现此错误:
Caused by: org.hibernate.QueryException: unexpected char: '#' [FROM com.krgcorporate.core.domain.access.Person p LEFT JOIN p.relatedContractRoleAttributions rcras WHERE rcras.contract.id = :#{#contract.id} AND rcras.relatedContractRole.code IN (:__$synthetic$__2)]
你知道为什么吗?
感谢您的帮助。
对于 JPA in
子句,您不能写括号。 (这里同样的问题同样的答案)
@Query ("FROM Person p " +
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code IN :#{#codes)")
老实说:我以前从未见过这种语法:#{#PARAM}
,我只知道:PARAM
。 - 但当它在另一个查询中工作时,也将在下一个查询中工作
@Franck Yapadesouci Anso:根据您的评论:您确定可以以这种方式使用 SPEL 表达式吗?试试 JPA 方式吧。
@Query ("SELECT p FROM Person p " + //+SELECT p
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract = :contract" + //without ID and SPEL
"AND rcras.relatedContractRole.code IN :codes") //without brackets and SPEL
我认为 org.springframework.data.jpa.repository.query.StringQuery 中存在问题。 spring-data-jpa-1.7.2.RELEASE(第 250..259 行)
case IN:
if (parameterIndex != null) {
checkAndRegister(new InParameterBinding(parameterIndex, expression), bindings);
} else {
checkAndRegister(new InParameterBinding(parameterName, expression), bindings);
}
result = query;
break;
因此,当 StringQuery 将 'in' 参数与 SPEL 绑定时,它会使用 @Query 注释中的字符串覆盖结果查询字符串。然后它将 'in' SPEL 替换为新绑定。
如果你改变
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code in :#{#code}"
进入
"WHERE rcras.relatedContractRole.code in :#{#code}" +
"AND rcras.contract.id = :#{#contract.id} "
它将解决您的问题
更新:
SpingDataJpa 团队已修复它。 https://jira.spring.io/browse/DATAJPA-712
我在 Spring Data JPA 上工作,我有一个实现 JpaRepository 的存储库接口。
我已经编写了这个完美运行的查询:
@Query ("FROM Person p " +
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code = :#{#code}")
Person findByContractAndRelatedContractRole(@Param ("contract") Contract contract, @Param ("code") String code);
现在我想写另一个可以在多个代码中找到的查询,所以我写了这个查询:
@Query ("FROM Person p " +
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code IN (:#{#codes})")
List<Person> findByContractAndRelatedContractRoles(@Param ("contract") Contract contract, @Param ("codes") String... codes);
但是当我启动我的应用程序时出现此错误:
Caused by: org.hibernate.QueryException: unexpected char: '#' [FROM com.krgcorporate.core.domain.access.Person p LEFT JOIN p.relatedContractRoleAttributions rcras WHERE rcras.contract.id = :#{#contract.id} AND rcras.relatedContractRole.code IN (:__$synthetic$__2)]
你知道为什么吗?
感谢您的帮助。
对于 JPA in
子句,您不能写括号。 (这里同样的问题同样的答案)
@Query ("FROM Person p " +
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code IN :#{#codes)")
老实说:我以前从未见过这种语法:#{#PARAM}
,我只知道:PARAM
。 - 但当它在另一个查询中工作时,也将在下一个查询中工作
@Franck Yapadesouci Anso:根据您的评论:您确定可以以这种方式使用 SPEL 表达式吗?试试 JPA 方式吧。
@Query ("SELECT p FROM Person p " + //+SELECT p
"LEFT JOIN p.relatedContractRoleAttributions rcras " +
"WHERE rcras.contract = :contract" + //without ID and SPEL
"AND rcras.relatedContractRole.code IN :codes") //without brackets and SPEL
我认为 org.springframework.data.jpa.repository.query.StringQuery 中存在问题。 spring-data-jpa-1.7.2.RELEASE(第 250..259 行)
case IN:
if (parameterIndex != null) {
checkAndRegister(new InParameterBinding(parameterIndex, expression), bindings);
} else {
checkAndRegister(new InParameterBinding(parameterName, expression), bindings);
}
result = query;
break;
因此,当 StringQuery 将 'in' 参数与 SPEL 绑定时,它会使用 @Query 注释中的字符串覆盖结果查询字符串。然后它将 'in' SPEL 替换为新绑定。
如果你改变
"WHERE rcras.contract.id = :#{#contract.id} " +
"AND rcras.relatedContractRole.code in :#{#code}"
进入
"WHERE rcras.relatedContractRole.code in :#{#code}" +
"AND rcras.contract.id = :#{#contract.id} "
它将解决您的问题
更新: SpingDataJpa 团队已修复它。 https://jira.spring.io/browse/DATAJPA-712