Исходный запрос с именованным параметром завершается с ошибкой: "Не все именованные параметры установлены"
Я хочу выполнить простой собственный запрос, но он не работает:
@Autowired
private EntityManager em;
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username");
em.setProperty("username", "test");
(int) q.getSingleResult();
Почему я получаю это исключение?
org.hibernate.QueryException: Not all named parameters have been set: [username]
Ответы
Ответ 1
Именованные параметры не поддерживаются JPA в собственных запросах, только для JPQL. Вы должны использовать позиционные параметры.
Именованные параметры соответствуют правилам для идентификаторов, определенных в разделе 4.4.1. Использование именованных параметров применяется к языку запросов Java Persistence и не определяется для собственных запросов. Только привязка позиционных параметров может быть портативно использована для собственных запросов.
Итак, используйте этот
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");
Хотя спецификация JPA не поддерживает именованные параметры в собственных запросах, некоторые версии JPA (например, Hibernate) могут поддерживать ее
Собственные SQL-запросы поддерживают позиционные, а также именованные параметры
Однако это связывает ваше приложение с конкретной реализацией JPA и, таким образом, делает его недоступным.
Ответ 2
После многих попыток я обнаружил, что вы должны использовать createNativeQuery
И вы можете отправлять параметры с помощью #
replacement
В моем примере
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();
Ответ 3
Используйте параметр Parameter из запроса.
Query q = (Query) em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");
Ответ 4
Это была ошибка, исправленная в версии 4.3.11
https://hibernate.atlassian.net/browse/HHH-2851
EDIT:
Лучший способ выполнить собственный запрос - использовать NamedParameterJdbcTemplate
Это позволяет вам получить результат, который не является управляемым объектом; вы можете использовать RowMapper и даже Карту именованных параметров!
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
final List<Long> resultList = namedParameterJdbcTemplate.query(query,
mapOfNamedParamters,
new RowMapper<Long>() {
@Override
public Long mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getLong(1);
}
});
Ответ 5
Вы вызываете setProperty
вместо setParameter
. Измените свой код на
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = :username");
em.setParameter("username", "test");
(int) q.getSingleResult();
и он должен работать.
Ответ 6
Я использую EclipseLink. Эта JPA разрешает следующий путь для собственных запросов:
Query q = em.createNativeQuery("SELECT * FROM mytable where username = ?username");
q.setParameter("username", "test");
q.getResultList();