简体   繁体   中英

unexpected token: '<function_name>' error when using hibernate, JPQL and postgres function

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.

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:

  1. Call your function by generic mechanism for custom functions:

use

function('function_that_return_array', '1,2,3,4')

instead of

function_that_return_array('1,2,3,4')
  1. Second option is to register your function: https://docs.jboss.org/hibernate/orm/5.1/javadocs/org/hibernate/dialect/Dialect.html#registerFunction-java.lang.String-org.hibernate.dialect.function.SQLFunction-

Example:

public class MyDialect extends PostgreSQLXXDialect {
    public MyDialect() {
        super();
        registerFunction("function_that_return_array", new StandardSQLFunction("function_that_return_array"));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM