HQL 无法查询 JSON 条数据
HQL cannot query JSON data
这是一个 NativeSql 工作正常:
session.createSQLQuery(select json_length(fav_goods) from customer where id=1).uniqueResult()
但是如果我像这样将它更改为 HQL,它就会引发错误
session.createQuery(select json_length(favGoods) from CustomerEntity where id=1).uniqueResult()
错误
Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'json_length' {originalText=json_length}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[DOT] DotNode: 'customeren0_.fav_goods' {propertyName=favGoods,dereferenceType=PRIMITIVE,getPropertyPath=favGoods,path={synthetic-alias}.favGoods,tableAlias=customeren0_,className=cn.phyer.bishe.entity.CustomerEntity,classAlias=null}
+-[IDENT] IdentNode: '{synthetic-alias}' {originalText={synthetic-alias}}
\-[IDENT] IdentNode: 'favGoods' {originalText=favGoods}
[select json_length(favGoods) from cn.phyer.bishe.entity.CustomerEntity where id=?1]
at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:220)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:155)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:600)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:709)
... 39 more
Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'json_length' {originalText=json_length}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[DOT] DotNode: 'customeren0_.fav_goods' {propertyName=favGoods,dereferenceType=PRIMITIVE,getPropertyPath=favGoods,path={synthetic-alias}.favGoods,tableAlias=customeren0_,className=cn.phyer.bishe.entity.CustomerEntity,classAlias=null}
+-[IDENT] IdentNode: '{synthetic-alias}' {originalText={synthetic-alias}}
\-[IDENT] IdentNode: 'favGoods' {originalText=favGoods}
在实体 class CustomerEntity
,字段 fav_goods
被命名为 favGoods
JPQL(或 HQL)不支持 JSON 函数。
请在此处查找所有支持的函数:
你必须坚持 SQL。
我遇到了类似的问题,我不得不使用 JSON_EXTRACT
mysql 函数。
- 扩展
MySQL5Dialect
class 以在 Hibernate 中注册 SQL 函数。
public class CustomMySQLDialect extends MySQL5Dialect {
public CustomMySQLDialect(){
super();
registerFunction(
"JSON_EXTRACT",
new StandardSQLFunction(
"JSON_EXTRACT",
StandardBasicTypes.STRING
)
);
}
}
- 在 Hibernate cfg 中注册自定义 MySQL 方言 xml
<property name="hibernate.dialect">com.testsigma.specification.CustomMySQLDialect</property>
- 在 Hibernate 中使用
CriteriaQuery
(JPQL) 和 SQL 函数。
Root<EntityType> subRoot = criteriaBuilder.from(Entity.class);
subQuery.select(builder.function("JSON_EXTRACT", String.class, subRoot.get("jsonData"), builder.literal("$.\"jsonPathField\"")));
query1.where(root.get("jsonKey").in(subQuery));
取自https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/
从 Hibernate 5.2 开始工作。3.Final,Spring Data JPA 2.1。9.RELEASE
这是一个 NativeSql 工作正常:
session.createSQLQuery(select json_length(fav_goods) from customer where id=1).uniqueResult()
但是如果我像这样将它更改为 HQL,它就会引发错误
session.createQuery(select json_length(favGoods) from CustomerEntity where id=1).uniqueResult()
错误
Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'json_length' {originalText=json_length}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[DOT] DotNode: 'customeren0_.fav_goods' {propertyName=favGoods,dereferenceType=PRIMITIVE,getPropertyPath=favGoods,path={synthetic-alias}.favGoods,tableAlias=customeren0_,className=cn.phyer.bishe.entity.CustomerEntity,classAlias=null}
+-[IDENT] IdentNode: '{synthetic-alias}' {originalText={synthetic-alias}}
\-[IDENT] IdentNode: 'favGoods' {originalText=favGoods}
[select json_length(favGoods) from cn.phyer.bishe.entity.CustomerEntity where id=?1]
at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:220)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:155)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:600)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:709)
... 39 more
Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'json_length' {originalText=json_length}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[DOT] DotNode: 'customeren0_.fav_goods' {propertyName=favGoods,dereferenceType=PRIMITIVE,getPropertyPath=favGoods,path={synthetic-alias}.favGoods,tableAlias=customeren0_,className=cn.phyer.bishe.entity.CustomerEntity,classAlias=null}
+-[IDENT] IdentNode: '{synthetic-alias}' {originalText={synthetic-alias}}
\-[IDENT] IdentNode: 'favGoods' {originalText=favGoods}
在实体 class CustomerEntity
,字段 fav_goods
被命名为 favGoods
JPQL(或 HQL)不支持 JSON 函数。
请在此处查找所有支持的函数:
你必须坚持 SQL。
我遇到了类似的问题,我不得不使用 JSON_EXTRACT
mysql 函数。
- 扩展
MySQL5Dialect
class 以在 Hibernate 中注册 SQL 函数。
public class CustomMySQLDialect extends MySQL5Dialect {
public CustomMySQLDialect(){
super();
registerFunction(
"JSON_EXTRACT",
new StandardSQLFunction(
"JSON_EXTRACT",
StandardBasicTypes.STRING
)
);
}
}
- 在 Hibernate cfg 中注册自定义 MySQL 方言 xml
<property name="hibernate.dialect">com.testsigma.specification.CustomMySQLDialect</property>
- 在 Hibernate 中使用
CriteriaQuery
(JPQL) 和 SQL 函数。
Root<EntityType> subRoot = criteriaBuilder.from(Entity.class);
subQuery.select(builder.function("JSON_EXTRACT", String.class, subRoot.get("jsonData"), builder.literal("$.\"jsonPathField\"")));
query1.where(root.get("jsonKey").in(subQuery));
取自https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/
从 Hibernate 5.2 开始工作。3.Final,Spring Data JPA 2.1。9.RELEASE