La consulta nativa con el parámetro nombrado falla con “No se han establecido todos los parámetros nombrados”

Quiero ejecutar una consulta nativa simple, pero no funciona:

@Autowired private EntityManager em; Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username"); em.setProperty("username", "test"); (int) q.getSingleResult(); 

¿Por qué recibo esta excepción?

 org.hibernate.QueryException: Not all named parameters have been set: [username] 

Los parámetros nombrados no son compatibles con JPA en consultas nativas, solo para JPQL. Debe usar parámetros posicionales.

Los parámetros con nombre siguen las reglas para los identificadores definidos en la Sección 4.4.1. El uso de parámetros con nombre se aplica al lenguaje de consulta de Java Persistence y no está definido para consultas nativas. Solo el enlace de parámetros posicionales se puede usar de forma portátil para consultas nativas.

Entonces, usa esto

 Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1"); q.setParameter(1, "test"); 

Si bien la especificación JPA no admite parámetros con nombre en consultas nativas, algunas implementaciones JPA (como Hibernate ) pueden soportarlo

Las consultas SQL nativas admiten parámetros posicionales y nominales

Sin embargo, esto asocia su aplicación a la implementación específica de JPA y, por lo tanto, la hace inaplicable.

Después de muchos bashs, descubrí que debes usar createNativeQuery Y puedes enviar parámetros usando # replacement

En mi ejemplo

 String UPDATE_lOGIN_TABLE_QUERY = "UPDATE OMFX.USER_LOGIN SET LOGOUT_TIME = SYSDATE WHERE LOGIN_ID = #loginId AND USER_ID = #userId"; Query query = em.createNativeQuery(logQuery); query.setParameter("userId", logDataDto.getUserId()); query.setParameter("loginId", logDataDto.getLoginId()); query.executeUpdate(); 

Yo uso EclipseLink. Este JPA permite la siguiente manera para las consultas nativas:

 Query q = em.createNativeQuery("SELECT * FROM mytable where username = ?username"); q.setParameter("username", "test"); q.getResultList(); 

Este fue un error corregido en la versión 4.3.11 https://hibernate.atlassian.net/browse/HHH-2851

EDITAR: La mejor forma de ejecutar una consulta nativa es usar NamedParameterJdbcTemplate. Te permite recuperar un resultado que no es una entidad administrada; ¡puede usar un RowMapper e incluso un Mapa de parámetros nombrados !

 private NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Autowired public void setDataSource(DataSource dataSource) { this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); } final List resultList = namedParameterJdbcTemplate.query(query, mapOfNamedParamters, new RowMapper() { @Override public Long mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getLong(1); } }); 

Use set Parameter desde la consulta.

 Query q = (Query) em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1"); q.setParameter(1, "test"); 

Está llamando a setProperty lugar de setParameter . Cambia tu código a

 Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username"); em.setParameter("username", "test"); (int) q.getSingleResult(); 

y debería funcionar