Подтвердить что ты не робот

Исходный запрос с именованным параметром завершается с ошибкой: "Не все именованные параметры установлены"

Я хочу выполнить простой собственный запрос, но он не работает:

@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]
4b9b3361

Ответ 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();