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

Экранирование символа двоеточия: "в запросах JPA

Я пытаюсь запустить собственный запрос через 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?

4b9b3361

Ответ 1

Я не знаю стандартного способа избежать символа двоеточия в запросе, который явно интерпретируется как префикс именованного параметра и, таким образом, смущает парсер запросов.

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

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

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

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

Именованный параметр является идентификатором который имеет префикс символа ":" . Именованные параметры чувствительны к регистру.

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

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

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

Ответ 2

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

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

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

Решение:

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

Ответ 3

Попробуйте следующее:

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();