Вложенная функция построителя критериев JPA 2.0 в статистической функции дает исключение QuerySyntaxException - PullRequest
1 голос
/ 11 марта 2020

У меня есть проект базы данных Postgres, который использует столбцы JSONB для хранения произвольных данных, я уже зарегистрировал функцию jsonb_extract_path_text. sh Я хочу написать JPA Criteria Query, который будет подсчитывать вхождения некоторых специфических c JSON ключей, это SQL эквивалент:

test=# select * from domain
test-# ;
 id  |     extra      
-----+----------------
   1 | {"test1": "a"}
  51 | {"test1": "b"}
 101 | {"test2": "b"}
 151 | {"test2": "e"}
 201 | {"test2": "f"}
(5 rows)

test=# select count(jsonb_extract_path_text(extra, 'test1')) from domain;
 count 
-------
     2
(1 row)

Теперь со следующим Критерий запроса

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
From from = cq.from(Domain.class);
cq.select(cb.count(cb.function("jsonb_extract_path_text", String.class, from.get("extra"), cb.literal("test1"))));
TypedQuery query = em.createQuery(cq);
List list = query.getResultList();

Я получаю следующее исключение

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found '(' near line 1, column 22 [select count(function('jsonb_extract_path_text', generatedAlias0.extra, 'test1')) from com.example.demo.Domain as generatedAlias0]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:297) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:155) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    ... 43 common frames omitted

Я не уверен, что спецификации JPA поддерживают такой подход, вложив пользовательскую функцию в агрегатную функцию или если это на самом деле ошибка в Hibernate.

Если это на самом деле не поддерживается стандартами JPA, какие еще варианты у меня есть для достижения такого подхода? У меня уже есть работа с Hibernate Criteria и функцией Projection.sqlProjection, но, насколько я знаю, это устарело.

Редактировать 1: Я действительно пробовал ту же реализацию, используя EclipseLink, и она работала правильно, поэтому я склонен подозревать, что это ошибка самой реализации JPA Hibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...