Estoy configurando Spring Data JPA Repo para trabajar con secuencias en una base de datos postgresql. Estaba asumiendo que esto sería bastante simple:
@Query(nativeQuery = true, value = "CREATE SEQUENCE IF NOT EXISTS ':seq_name' START WITH :startAt") fun createSequence(@Param("seq_name") seq_name: String, @Param("startAt") startAt: Long = 0) @Query(nativeQuery = true, value = "SELECT nextval(':seq_name')") fun nextSerial(@Param("seq_name") seq_name: String) : Long @Query(nativeQuery = true, value = "DROP SEQUENCE IF EXISTS ':seq_name'") fun dropSequence(@Param("seq_name") seq_name: String) @Query(nativeQuery = true, value = "setval(':seq_name', :set_to, false") fun setSequence(@Param("seq_name") seq_name: String, @Param("set_to") setTo: Long) Pero por alguna razón obtengo org.springframework.dao.InvalidDataAccessApiUsageException: Parameter with that name [seq_name] did not exist; cada vez que intento llamar al método. ¿Alguna idea de por qué puede pasar esto?
Ok, según la respuesta de @StanislavL y después de algunas depuraciones, ahora tengo una solución que funciona. Como señaló @posz, no puedo vincular identificadores, lo que significa que tengo que codificar las consultas. Moví el código de una interfaz JPA a un servicio implementado que no es tan bueno pero funciona.
@Service open class SequenceService (val entityManager: EntityManager){ @Transactional fun createSequence(seq_name: String, startAt: Long = 0) { val query = entityManager.createNativeQuery("CREATE SEQUENCE IF NOT EXISTS ${seq_name} START ${startAt}") with(query){ executeUpdate() } } @Transactional fun nextSerial(seq_name: String) : Long { val query = entityManager.createNativeQuery("SELECT nextval(:seq_name)") with(query){ setParameter("seq_name", seq_name) val result = singleResult as BigInteger return result.toLong() } } @Transactional fun dropSequence(seq_name: String) { val query = entityManager.createNativeQuery("DROP SEQUENCE IF EXISTS ${seq_name}") with(query){ executeUpdate() } } @Transactional fun setSequence(seq_name: String, setTo: Long){ val query = entityManager.createNativeQuery("SELECT setval(:seq_name, :set_to, false)") with(query){ setParameter("seq_name", seq_name) setParameter("set_to", setTo) singleResult } } } Espero que esto sea útil para la próxima persona que intente trabajar directamente con secuencias cuando usar @SequenceGenerator no sea una opción.