意外令牌:<function_name>使用休眠、JPQL 和 postgres 函数时出现""错误



我将PostgreSQL 9.6Hibernate 5.4.8Java 8和Spring框架一起使用。我需要调用一个postgres函数

CREATE OR REPLACE FUNCTION function_that_return_array(givenIds character varying(255)) RETURNS int[] AS
'
BEGIN
RETURN string_to_array($1,'','');
END
' LANGUAGE plpgsql;

在JPQL查询中

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))";

并使用实体管理器:

@Autowired
private final EntityManager entityManager;
// ...
this.entityManager.createQuery(JPQL_QUERY, CustomProjection.class)
.setParameter("ids", "1,2,3")
.getResultList();

并导致以下异常:

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]

上面的例子非常简单,但它正确地表示了生产问题。当我在本机SQL中调用上述函数时,它可以完美地工作:

select *
from some_entity e 
where e.id = ANY(function_that_return_array('1,2,3,4'))

有人知道如何在JPQL和Hibernate中调用postgres函数吗?或者有人能指出我做错了什么吗?我读了很多像这样的文章,所以有问题,我尝试了几十个的组合,但到目前为止没有成功。提前谢谢。

在Hibernate方言中,您不能直接调用未注册的自定义数据库函数。clear中的异常,hibernate对您的功能一无所知:

unexpected token: function_that_return_array

这里有两个选项:

  1. 通过自定义函数的通用机制调用函数:

使用

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

而不是

function_that_return_array('1,2,3,4')
  1. 第二个选项是注册您的函数:https://docs.jboss.org/hibernate/orm/5.1/javadocs/org/hibernate/dialect/Dialect.html#registerFunction-java.lang.String-org.hibernate.dialect.function.SQLFunction-

示例:

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

最新更新