Estou tentando usar nomes e valores de colunas dinâmicas em uma consulta no 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
Mas isso me dá
org.springframework.dao.InvalidDataAccessResourceUsageException: Nenhum argumento para o parâmetro nomeado ':query%'
Por que?
Você não pode concatenar
%
dentro da string de consulta. Deve ser concatenado externamente.A melhor solução é adicionar um novo parâmetro:
constructedQuery.setParameter("queryWildcard", "%" + query + "%")
Portanto, seu literal SQL final seria: