Собственные Запросы JPA/Hibernate не распознают Параметры

Я использую Hibernate/JPA для выполнения собственных запросов PostGIS. Проблема с этими запросами состоит в том, что им нужны параметры, которые не имеют классического X = форма 'значения'.

Например, следующий катастрофический отказ строк

 String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(:lon :lat)'),4326), 0.1)";
  Query query = Cell.em().createNativeQuery(queryString, Cell.class);
  query.setParameter("lon", longitude);
  query.setParameter("lat", latitude);

play.exceptions.JavaExecutionException: org.hibernate.QueryParameterException: could not locate named parameter [lon]
 at play.mvc.ActionInvoker.invoke(ActionInvoker.java:259)
 at Invocation.HTTP Request(Play!)
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: could not locate named parameter [lon]
 at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:358)

Следующий запрос работает однако:

String queryString = String.format("select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(%f %f)'),4326), 0.1)", longitude, latitude);
Query query = Cell.em().createNativeQuery(queryString, Cell.class);

(но это является СКЛОННЫМ К ВНЕДРЕНИЮ SQL...),

Делает любой знает, как использовать setParameter() в этом случае?

46
задан Pascal Thivent 29 June 2010 в 23:16
поделиться

3 ответа

Возможно, вы можете заменить

'POINT(:lon :lat)'

на

'POINT(' || :lon || ' ' || :lat || ')'

Таким образом параметры находятся за пределами постоянных строк и должны распознаваться синтаксическим анализатором запросов.

18
ответ дан 26 November 2019 в 20:14
поделиться

Использование именованных параметров не определено для собственных запросов. Из спецификации JPA (раздел 3.6.3 Именованные параметры ):

Именованные параметры соответствуют правилам для идентификаторы, определенные в разделе 4.4.1. Использование именованных параметров применяется к язык запросов Java Persistence, и не определен для собственных запросов. Только привязка позиционного параметра может быть переносимым для собственных запросов .

Поэтому попробуйте вместо этого следующее:

String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(?1 ?2)'),4326), 0.1)";
Query query = Cell.em().createNativeQuery(queryString, Cell.class);
query.setParameter(1, longitude);
query.setParameter(2, latitude);

Обратите внимание, что в JPA> = 2.0 вы можете использовать именованных параметров в собственных запросах.

81
ответ дан 26 November 2019 в 20:14
поделиться

Итак, идея заключалась в том, чтобы использовать трюк с конкатенацией, предложенный Йорном Хорстманном, чтобы заставить postgres распознать параметры. Следующий код работает :

String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(' || :lon || ' ' || :lat || ')'),4326), 0.2)";
Query query = Cell.em().createNativeQuery(queryString, Cell.class);
query.setParameter("lon", longitude);
query.setParameter("lat", latitude);

Большое спасибо за ваши ответы!

2
ответ дан 26 November 2019 в 20:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: