Reputation: 5231
I have spring data repository interface like this:
public interface MyEntityRepository extends
JpaRepository<MyEntity, Long> {
@Query(nativeQuery = true, value = "select * from my_func(:myList)")
Page<MyEntity> findBy(
@NonNull @Param("myList") List<String> myList,
@NonNull Pageable pageable);
}
Postgres' function I have defined like this (but I can change it if I did it wrong):
CREATE OR REPLACE FUNCTION my_func(variadic myList text[])
RETURNS SETOF myEntityTable AS $$
... some logic
select * from myEntityTable t where t.foo in (myList);
When I call this repository method I got this error:
ERROR: operator does not exist: character varying = text[]
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Where: PL/pgSQL function f_najdi_autorizaciu_na_spracovanie(text[]) line 28 at RETURN QUERY
Can you please tell me what type should I use in my postgres function? Thank you in advice.
EDIT: I cannot use native query above repository method and pass there list into IN clause because I have in DB function more logic, variables and so on ... it have to be DB function.
Upvotes: 5
Views: 16493
Reputation: 9532
Not sure whether this add a lot of value, I just hope it helps.
The final format that the PostgreSQL function expects from a list as the input is of the following a pattern, using an array:
select my_func(array['item1','item2']::my_type[]);
See a full example on Database Administrators.SE.
In your case:
select my_func(array['item1','item2']::text[]);
and I found out in my own tests that
select my_func(array['item1','item2']);
should already be enough.
Then, the only aim is to get this format from your original java type. Thihs has been answered by the other question. This answer is just about showing the aim of it all.
Upvotes: 0
Reputation: 30309
I used the following workaround solution in the similar situation:
1) Created two helper functions:
-- Convert a variable number of text arguments to text array
-- Used to convert Java collection to the text array
--
create or replace function list_to_array(variadic _list text[]) returns text[] language sql as $$
select _list;
$$;
-- Convert the bytea argument to null.
-- Used to convert Java null to PostgreSQL null
--
create or replace function list_to_array(_list bytea) returns text[] language sql as $$
select null::text[];
$$;
2) Used any
instead of in
in the main function, for example:
create or replace function my_func(_params text[])
returns table (field1 text, field2 text)
language sql as
$$
select
t.field1 as field1,
t.field2 as field2,
from
my_table t
where
array_length(_params, 1) is null or t.foo = any(_params);
$$;
3) Then used them in a repository method, for example:
@NonNull
@Query(value = "select ... from my_func(list_to_array(?1))", nativeQuery = true)
List<MyProjection> getFromMyFunc(@Nullable Set<String> params, @NonNull Pageable page);
Upvotes: 6
Reputation: 220787
I'm afraid I don't know how to do this with Spring Data JPA, but with plain JDBC, you'd have to simply cast the bind variable to text[]
and pass a String[]
type instead of a list. For example:
try (PreparedStatement s = conn.prepareStatement("select * from my_func(?::text[])")) {
s.setObject(1, myList.toArray(new String[0]));
try (ResultSet rs = s.executeQuery()) {
// ...
}
}
The key message here is that the JDBC driver will expect an array, not a list.
Upvotes: 0