Reputation: 652
I'm using PostgreSQL 9.6
with Hibernate 5.4.8
, Java 8
and Spring framework. I need to call a postgres function
CREATE OR REPLACE FUNCTION function_that_return_array(givenIds character varying(255)) RETURNS int[] AS
'
BEGIN
RETURN string_to_array($1,'','');
END
' LANGUAGE plpgsql;
within JPQL query
private static final String JPQL_QUERY =
" SELECT NEW com.package.CustomProjection( " +
" e.id, " +
" e.value " +
" ) " +
" FROM SomeEntity e " +
" WHERE e.id = ANY(function_that_return_array(:ids))";
and using entity manager:
@Autowired
private final EntityManager entityManager;
// ...
this.entityManager.createQuery(JPQL_QUERY, CustomProjection.class)
.setParameter("ids", "1,2,3")
.getResultList();
and it results in following exception:
antlr.NoViableAltException: unexpected token: function_that_return_array
at org.hibernate.hql.internal.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1055) [hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:748) [hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.subQuery(HqlBaseParser.java:3910) [hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.quantifiedExpression(HqlBaseParser.java:3515) [hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.unaryExpression(HqlBaseParser.java:3373) [hibernate-core-5.4.8.Final.jar:5.4.8.Final]
...
antlr.MismatchedTokenException: expecting EOF, found ')'
at antlr.Parser.match(Parser.java:211) ~[antlr-2.7.7.jar:?]
at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:215) [hibernate-core-5.4.8.Final.jar:5.4.8.Final]
The above example is very simplified but it correctly represents the production problem. When I call above function in native SQL it works perfectly:
select *
from some_entity e
where e.id = ANY(function_that_return_array('1,2,3,4'))
Does anyone know how to call a postgres function within JPQL and Hibernate or can point me out what I am doing wrong? I was reading many articles like this one, SO questions and I was trying dozens of combinations but with no success so far. Thanks in advance.
Upvotes: 0
Views: 753
Reputation: 170
In Hibernate dialect you cannot call directly not registered custom database functions. The exception in clear, hibernate knows nothing about your function:
unexpected token: function_that_return_array
You have two options here:
use
function('function_that_return_array', '1,2,3,4')
instead of
function_that_return_array('1,2,3,4')
Example:
public class MyDialect extends PostgreSQLXXDialect {
public MyDialect() {
super();
registerFunction("function_that_return_array", new StandardSQLFunction("function_that_return_array"));
}
}
Upvotes: 1