You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data JPA动态列名查询报错:缺少':query%'命名参数

问题分析:Spring Data JPA动态查询参数异常原因

问题代码

interface CustomFooRepository {
    fun findByValueIgnoreCase(query: String, type: RequestType): List<Foo>
}

class CustomFooRepositoryImpl(
    @PersistenceContext private val entityManager: EntityManager
) : CustomFooRepository {

    override fun findByValueIgnoreCase(query: String, type: RequestType): List<Foo> {
        val column = when (type) {
            RequestType.first_name -> "first_name"
            RequestType.last_name -> "last_name"
            RequestType.email -> "email"
        }

        val sql = """
            SELECT 
                *,
                SIMILARITY(:column, :query) AS score
            FROM foo
            WHERE :column iLIKE %:query%
            ORDER BY score DESC NULLS LAST, :column
            LIMIT 20;
        """

        val constructedQuery = entityManager.createNativeQuery(sql, Foo::class.java)
        constructedQuery.setParameter("column", column)
        constructedQuery.setParameter("query", query)
        return constructedQuery.resultList as List<Foo>
    }
}

interface FooRepository : JpaRepository<Foo, Long>, CustomFooRepository

运行异常

org.springframework.dao.InvalidDataAccessResourceUsageException: No argument for named parameter ':query%'


异常原因

  1. 通配符写法错误:SQL里的%:query%会被JPA识别成一个名为:query%的完整参数,而不是:query参数加上通配符。JPA找不到这个不存在的参数,直接抛出异常。
  2. 动态列名不能用参数绑定:代码里用:column绑定列名是无效的,JPA的参数绑定只支持值类型(比如字符串、数字),不支持列名、表名这类SQL标识符。实际执行时会把:column替换成字符串值(比如'first_name'),导致SQL逻辑变成WHERE 'first_name' iLIKE ...,完全不符合预期。排序字段:column也存在同样的问题。

修正思路

  • 处理通配符:把通配符拼到参数值里,而不是SQL语句中。比如:
    val wrappedQuery = "%$query%"
    constructedQuery.setParameter("query", wrappedQuery)
    
    对应的SQL改成WHERE ... iLIKE :query
  • 动态列名字符串拼接:因为RequestType是枚举,不存在SQL注入风险,可以直接把列名拼到SQL中:
    val sql = """
        SELECT 
            *,
            SIMILARITY($column, :query) AS score
        FROM foo
        WHERE $column iLIKE :query
        ORDER BY score DESC NULLS LAST, $column
        LIMIT 20;
    """
    

内容的提问来源于stack exchange,提问作者four-eyes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:13:17