6

I have a native postgresql query (opts - jsonb array):

select * from table users jsonb_exists_any(opts, ARRAY['CASH', 'CARD']);

it works fine in my database console and I'm getting a result:

user1, ['CASH','CARD']
user2, ['CASH']
user3, ['CARD']

but when I want to use it in my spring data jpa application as:

@Query(value = "select * from users where jsonb_exists_any(opts, ARRAY[?1])", nativeQuery = true)
List<Users> findUsers(Set<String> opts);

I'm getting an error:

h.e.j.s.SqlExceptionHelper - SQL Error: 0, SQLState: 42883 h.e.j.s.SqlExceptionHelper - ERROR: function jsonb_exists_any(jsonb, record[]) does not exist

because that query converts to:

select
    * 
from
    users 
where
    jsonb_exists_any(opts, ARRAY[(?, ?)])

Is there a way to pass parameters as an array? i.e. without brackets around ?, ?

3
  • You were able to solve it? Commented Aug 19, 2021 at 9:38
  • @damike I haven't found nothing better than soung's answer Commented Aug 20, 2021 at 10:50
  • I found a solution yesterday: CREATE OR REPLACE FUNCTION wrap_varchar(VARIADIC params VARCHAR[]) RETURNS SETOF VARCHAR[] AS $$ SELECT params; $$ LANGUAGE SQL; Then SELECT jsonb_exists_any('{"name": "Joe Smith", "age": 28, "sports": ["football"]}', wrap_varchar('age','address')); which works with spring data. You can replace 'age','address' with :filter Commented Aug 21, 2021 at 12:57

3 Answers 3

6

can you try this :

@Query(value = "select * from users where jsonb_exists_any(opts, string_to_array(?1, ','))", nativeQuery = true)
List<Users> findUsers(String listStringSeparatedByComma);

Notice you have to replace the Set parameter by a String.

Sign up to request clarification or add additional context in comments.

1 Comment

yeah, your solution works, but I'm curious if there is an option to somehow use a list or array without converting and joining values to a string
0

this will work:

@Query(value = "with array_query as (select array_agg(value) as array_value from (select (json_each_text(row_to_json(row_values))).value from (values ?1) row_values) col_values)"+
" select * from users where jsonb_exists_any(opts, (select array_value from array_query))", nativeQuery = true)
List<Users> findUsers(Set<String> opts);

Comments

-1

I faced the same issue using jsonb_exists_any function with Spring Data. To avoid additional brackets ARRAY[(?, ?)] I changed method signature to accept String[] instead of Set or any Collection:

@Query(value = "select * from users where jsonb_exists_any(opts, :values)", nativeQuery = true)
List<Users> findUsers(@Param("values") String[] values);

and added conversion into array in Service layer:

// Set<String> opts = Set.of("a","b","c");
repository.findUsers(opts.toArray());

Once it is array, you can apply any other functions, for example use filter only if array is not empty:

@Query(value = "select * from users 
                where (array_length(:values, 1) is null or 
                jsonb_exists_any(opts, :values))"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.