使用@Query命名参数报错排查:关联MappedSuperclass审计类问题
我来帮你捋捋这个问题哈,先看抛出的异常信息,核心问题是参数绑定失败,结合你的代码和查询语句,主要有这几个地方需要修正:
1. 查询语句里的参数名语法错误
你写的@Query语句里,有几处: createdDate的写法(冒号后面跟了空格),这是直接导致报错的原因!Spring Data JPA会把这个当成参数名包含空格,自然找不到你方法里定义的createdDate参数。
修正方式:把所有带空格的参数引用改成无空格的,比如把: createdDate改成:createdDate,所有出现的地方都要改。
举个错误片段的对比:
错误写法:
where ap.clientAccount.accountId =:accountId and pf.createdDate =: createdDate
修正后:
where ap.clientAccount.accountId =:accountId and pf.createdDate =:createdDate
2. 子查询逻辑存在冗余(虽不是直接报错原因,但建议优化)
看你写的子查询:
ap.createdDate = (select MAX(pf.createdDate) as date from ActualPortfolio pf where ap.clientAccount.accountId =:accountId and pf.createdDate =:createdDate)
这里你先限定了pf.createdDate =:createdDate,再取MAX值,结果就是你传入的createdDate本身,完全没必要套个子查询,直接写成ap.createdDate =:createdDate就行。
另外第二个子查询里,你把MAX后的日期转成字符串'YYYY-MM-DD 00:00:00'再和hd.dateTime比较,如果hd.dateTime是时间类型的话,这种字符串比较容易出问题(比如时区、类型不匹配),建议用JPA支持的时间截断函数,比如Hibernate的trunc(:createdDate)来直接获取日期的零点时间,这样更稳妥。
3. 确保方法参数的绑定准确
异常里提到了Optional[createdDate],如果你的Repository方法参数是Optional<LocalDateTime>类型,或者编译时没开启Java的-parameters选项(导致参数名无法被反射获取),最好用@Param注解显式指定参数名,避免绑定混乱。比如:
List<CurrencyConversion> getInstrumentForCurrencyConverstion( @Param("accountId") String accountId, @Param("createdDate") LocalDateTime createdDate );
修正后的完整查询示例
@Query("select new com.brite.domain.CurrencyConversion(ins.id,ins.contractType,ins.symbol,ins.exchange,ins.currency,ap.allocationQty,ap.createdDate,ca.baseCurrency,hd.close) " + "from ActualPortfolio as ap " + "JOIN Instrument as ins on ins.id=ap.instrument.id " + "JOIN HistoricalData as hd on hd.instrumentId = ins.id " + "Join ClientAccount as ca on ca.accountId = ap.clientAccount.accountId " + "where ap.clientAccount.accountId =:accountId " + "and ap.createdDate =:createdDate " + "and hd.dateTime = trunc(:createdDate)")
如果你的JPA提供商不支持trunc函数,可以换成对应数据库的时间处理函数,比如PostgreSQL的function('date_trunc', 'day', :createdDate)。
内容的提问来源于stack exchange,提问作者raja yadav

