简体   繁体   中英

HQL cannot query JSON data

This is a NativeSql work fine: session.createSQLQuery(select json_length(fav_goods) from customer where id=1).uniqueResult()

But if I change it to HQL like this follow,it well raised a Error session.createQuery(select json_length(favGoods) from CustomerEntity where id=1).uniqueResult()

error

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}

At the entity class CustomerEntity ,field fav_goods is been named as favGoods

JPQL (or HQL) does not support JSON Functions.

Please find all supported functions here:

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#hql-functions

You have to stick with SQL.

I had a similar problem and I had to use JSON_EXTRACT mysql function.

  1. Extend the MySQL5Dialect class to register the SQL Function in Hibernate.
public class CustomMySQLDialect extends MySQL5Dialect {
    public CustomMySQLDialect(){
        super();
        registerFunction(
                "JSON_EXTRACT",
                new StandardSQLFunction(
                        "JSON_EXTRACT",
                        StandardBasicTypes.STRING
                )
        );
    }
}
  1. Register the Custom MySQL Dialect in Hibernate cfg xml
<property name="hibernate.dialect">com.testsigma.specification.CustomMySQLDialect</property>
  1. Use CriteriaQuery (JPQL) with SQL Function within Hibernate.
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));

Taken from https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/

Working as of Hibernate 5.2.3.Final, Spring Data JPA 2.1.9.RELEASE

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