Экранирование символа двоеточия ':' в запросах JPA - PullRequest
13 голосов
/ 13 ноября 2010

Я пытаюсь выполнить собственный запрос через JPA, который использует символ «:». Конкретный экземпляр использует пользовательскую переменную MySQL в запросе:

SELECT foo, bar, baz, 
    @rownum:= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    := foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc 

Код JPA:

Query q = getEntityManager().createNativeQuery(query, SomeClass.class);
return q.getResultList();

Однако, это дает мне исключение из-за того, что мне не разрешают следовать за «:» с пробелом. Я пытался избежать их с помощью обратной косой черты, я пытался избежать их, удваивая их. Есть ли способ сделать это на самом деле, или я SOL?

Ответы [ 3 ]

42 голосов
/ 20 марта 2015

Я сталкивался с подобным опытом при использовании функции postgresql json в собственном запросе JPA.

select * from component where data ::json ->> ?1 = ?2

JPA выдаст ошибку, что я не установил названный параметр: json.

Решение:

select * from component where data \\:\\:json ->> ?1 = ?2
1 голос
/ 13 ноября 2010

Мне не известен стандартный способ экранирования символа двоеточия в запросе, который явно интерпретируется как префикс именованного параметра и, таким образом, сбивает с толку синтаксический анализатор запроса.

Я бы предложил создать ииспользуйте функции SQL, если это возможно.В зависимости от вашего провайдера, могут быть и другие варианты (например, использование другого символа и замена выбранного символа на : в перехватчике), но по крайней мере предыдущее предложение сохранит ваш JPA-код переносимым между провайдерами.

PS: если вы используете Hibernate, к HHH-1237 .

добавлен очень старый патч. Обновление: В "интересном" абзаце естьСпецификация JPA 1.0 об именованных параметрах и собственных запросах:

3.6.3 Именованные параметры

Именованный параметр - это идентификатор, к которому добавляется символ «:».Именованные параметры чувствительны к регистру.

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

Имена параметров, передаваемые в методы setParameter API Query, не включают префикс ":".

Это на самом деле не поможет, но ваш случай - сильный намек на то, что «:» в нативных запросах даже не следует рассматривать (по крайней мере, без способа избежать его или отключить его обнаружение).

0 голосов
/ 03 октября 2015

Попробуйте это:

String query =
"SELECT foo, bar, baz, 
    @rownum \\\\:= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    \\\\:= foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc  -- escape='\' ";

Query q = getEntityManager().createNativeQuery(query, SomeClass.class);
return q.getResultList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...