我正在使用springjpa和postgresql,我的数据库中有一个字段为bitint数组类型,而在Java中,这是一个Long值。
我正在使用spring jpa CriteriaBuilder&Specification来创建数组位置函数:
private Predicate toPredicate(String propName, Query q, Root<T> root, CriteriaBuilder cb) {
...
return cb.isNotNull(cb.function("array_position", Integer.class,
xx expression,
cb.literal(q.value))); // q.value is a long type value
}
并且当我执行查询时出错:
Hibernate:
select
distinct ruletemp0_.id as id1_119_,
ruletemp0_.applicant as applican2_119_,
ruletemp0_.approver as approver3_119_,
ruletemp0_.devices as devices4_119_,
ruletemp0_.end_time as end_time5_119_,
ruletemp0_.execution_id as executio6_119_,
ruletemp0_.execution_type as executio7_119_,
ruletemp0_.extra as extra8_119_,
ruletemp0_.rule_id as rule_id9_119_,
ruletemp0_.start_time as start_t10_119_,
ruletemp0_.state as state11_119_,
ruletemp0_.user_id as user_id12_119_
from
tbl_ruletemp ruletemp0_
where
array_position(ruletemp0_.user_id, 1) is not null
or array_position(ruletemp0_.user_id, 2) is not null
2019-10-30 10:44:42.230 [WARN ] [main] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper::logExceptions] SQL Error: 0, SQLState: 42883
2019-10-30 10:44:42.230 [ERROR] [main] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper::logExceptions] ERROR: function array_position(bigint[], integer) does not exist
建议:No function matches the given name and argument types. You might need to add explicit type casts.
似乎jpa无法识别我的Long类型值,我尝试使用:
BigInteger bigInteger = new BigInteger(String.valueOf(q.value));
return cb.isNotNull(cb.function("array_position", Integer.class,
toExpression(propName, root),
cb.literal(bigInteger)));
仍然错误。如果我直接在pg中执行SQL查询:
select * from tbl_ruletemp t where array_position(t.user_id, cast(1 as BIGINT)) is not null;
将起作用。
和想法?
您可以使用条件构建器创建cast
表达式,但是可能没有必要。不要将数字用作文字,而应将其作为参数传递。
ParameterExpression<BigInteger> pid = cb.parameter(BigInteger.class, "pid");
return cb.isNotNull(cb.function("array_position", Integer.class,
toExpression(propName, root),
pid));
然后像往常一样简单地绑定参数。并且由于您使用的是数组,所以最好使用arrayoverlap
而不是链接array_position
调用和or
表达式。