Как внедрить параметр List в виде текстового массива в собственный запрос, отличный от IN, в Spring Data JPA?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как внедрить параметр List в виде текстового массива в собственный запрос, отличный от IN, в Spring Data JPA?

Сообщение Anonymous »

Я чего-то не понимаю во внедрении параметров JPA @Query: я ожидаю, что любой List
станет {...,... }::TEXT (или ::VARCHAR) в SQL, поскольку это очевидный способ представления списка строк в SQL.

Код: Выделить всё

@Query(
"""
SELECT ... FROM ...
WHERE sql_function(:myParam)
^^^ I expect that to be injected as '{a,b,c,etc}'
""",
nativeQuery = true,
)
fun findAll(myParam: List): List
Проверка запроса вручную

Код: Выделить всё

jsonb_contains_any(jsonb_data jsonb, collection_path text[], collection_key text, search_values text[])
— это написанная мной специальная
функция PostgreSQL. Он тщательно протестирован и работает должным образом, когда я запускаю его вручную:

Код: Выделить всё

SELECT * FROM logbook_reports
WHERE log_type = 'PNO' AND jsonb_contains_any(value, '{catchOnboard}', 'species', NULL);
SELECT * FROM logbook_reports
WHERE log_type = 'PNO' AND jsonb_contains_any(value, '{catchOnboard}', 'species', '{}');
SELECT * FROM logbook_reports
WHERE log_type = 'PNO' AND jsonb_contains_any(value, '{catchOnboard}', 'species', '{HKE}');

Код: Выделить всё

Successfully run. Total query runtime: 258 msec.
1 rows affected.
Первая попытка
Сначала я надеялся, что это сработает «из коробки»:

Код: Выделить всё

@Query(
"""
SELECT *
FROM logbook_reports
WHERE log_type = 'PNO'
AND jsonb_contains_any(value, '{catchOnboard}', 'species', (:specyCodes))
""",
nativeQuery = true,
)
fun findAll(specyCodes: List): List
После запроса specyCodes=['HKE'] я получаю следующую ошибку:

Код: Выделить всё

24-04-11 19:39:58.973 DEBUG o.s.w.f.CommonsRequestLoggingFilter      : After request [GET /bff/v1/prior_notifications?specyCodes=HKE]
24-04-11 19:39:58.974 ERROR o.a.j.l.DirectJDKLog                     : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessResourceUsageException: JDBC exception executing SQL [
SELECT *
FROM logbook_reports
WHERE log_type = 'PNO' AND jsonb_contains_any(value, '{catchOnboard}', 'species', (?))
] [ERROR: function jsonb_contains_any(jsonb, unknown, unknown, character varying) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Position: 83] [n/a]; SQL [n/a]] with root cause
Вы заметите, что он даже «не понимает», что «вид» явно является типом TEXT. Что еще это может быть 🤔? И
Интересно, как он может потеряться в чем-то, что Postgre изначально понимает (запрос вручную)?
Вторая попытка
Тогда я попробовал привести все параметры:

Код: Выделить всё

@Query(
"""
SELECT *
FROM logbook_reports
WHERE log_type = 'PNO'
AND jsonb_contains_any(value, ARRAY['catchOnboard'], CAST('species' AS TEXT), CAST(:specyCodes AS TEXT[]))
""",
nativeQuery = true,
)
fun findAll(specyCodes: List): List
Тот же запрос (

Код: Выделить всё

specyCodes=['HKE']
):

Код: Выделить всё

24-04-11 19:48:02.601 DEBUG o.s.w.f.CommonsRequestLoggingFilter      : After request [GET /bff/v1/prior_notifications?specyCodes=HKE]
24-04-11 19:48:02.605 ERROR o.a.j.l.DirectJDKLog                     : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: JDBC exception executing SQL [
SELECT *
FROM logbook_reports
WHERE jsonb_contains_any(value, ARRAY['catchOnboard'], CAST('species' AS TEXT), CAST((?) AS TEXT[]))
] [ERROR: malformed array literal: "HKE"
Detail: Array value must start with "{" or dimension information.] [n/a]; SQL [n/a]] with root cause
Он просто вставляет «HKE», как если бы это была простая строка...

Подробнее здесь: https://stackoverflow.com/questions/783 ... ative-quer
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»