Estoy tratando de hacer que esta consulta funcione en JPA:
SELECT * FROM contrat WHERE contrat_json @> '{"nom" :"hever"}'; Funciona perfectamente con postgresql pero cuando lo integro con JPA me sale el siguiente error:
El parámetro con esa posición [1] no existía
Mi código:
@Transactional @Query(nativeQuery = true,value = "select p from Contrat p where contrat_json @> '{\"nom\":\":nom\"}'") public List<Contrat> findByNomRestrict(@Param("nom") String nom); Creo que no reconoce @> a pesar de la consulta nativa, ¿tienes una idea?
Los titulares de parámetros no se entienden dentro de los literales: '...:nom...' contendrá los caracteres :nom , no los valores vinculados de nom .
Para PostgreSQL 9.5 (y versiones posteriores), use:
SELECT * FROM contrat WHERE contrat_json @> jsonb_build_object('nom', :nom)Para 9.4:
SELECT * FROM contrat WHERE contrat_json @> CAST(json_build_object('nom', :nom) AS jsonb) Para 9.3 (y versiones anteriores), no hay un operador de contención JSON (ni del tipo jsonb ).
Tuve un problema similar con mi consulta nativa. El nombre del campo jsonb se llama data y es simple
{ "name" : "genderList", "displayName" : "gender list" }Quiero buscar por nombre con JpaRepository, y aquí está mi Repositorio
@Repository public interface LookupListRepository extends JpaRepository<LookupList, UUID> { @Query(value = "SELECT * FROM lookup_list WHERE data->>'name' = :name", nativeQuery = true) List<LookupList> findByName(@Param("name") String name); }Necesitas nativeQuery = true . Con nativeQuery = true , esto también funciona.
SELECT * FROM lookup_list WHERE jsonb_extract_path_text(data, 'name') = :nameVeo su anotación @Transactional, asumo que tiene la consulta nativa además del método de servicio de la aplicación. ¿Puede intentar mover todas las consultas nativas en el repositorio y usar JpaRepository, y usar el método de repositorio en su servicio de aplicación? Así es como mi servicio de aplicación usa el repositorio.
public class LookupListServiceImpl implements LookupListService { @Autowired LookupListRepository lookupListRepository; @Override @Transactional public void changeLookupList(LookupListDto lookupListDto) { List<LookupList> lookupLists = lookupListRepository.findByName(lookupListDto.getName()); ... } }Referencia para el repositorio JPA http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html
Con PostgreSQL y JSON, probablemente se encontrará con la necesidad ? u otros operadores extraños, por lo que es mejor que use sus funciones equivalentes en su lugar. Puede buscarlos en la consola psql como este \doS+ @> .
Su consulta no es nativa, como dice el parámetro.
select p from Contrat p where...Solo le dará un error cuando llegue a la base de datos.
Prueba algo como
@Query(nativeQuery = true, value = "select * from Contrat where jsonb_contains(contrat_json, :nom )") y simplemente enlace "{\"nom\":\"" + param + "\"}" como parámetro