问题描述
我正在尝试使用JPA条件执行此查询:
我正在尝试使用JPA条件执行此查询:
SELECT format(data_creazione_pratica,'dd/MM/yyyy')
FROM tcigdbexternal.ristoratori_svil.pratica
...所以我写了这个JAVA代码:
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<String> criteria = criteriaBuilder.createquery(String.class);
final Root<Pratica> root = criteria.from(Pratica.class);
criteria.select(criteriaBuilder.function("FORMAT",String.class,root.get("dataInserimento"),criteriaBuilder.literal("dd/MM/yyyy")));
...但是我得到了这个异常:
task-1|ERROR|requestId_6|i.p.r.m.a.w.r.c.PraticaController[PraticaController.java:50]|Exception occurred
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException:
No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode \-[METHOD_CALL] MethodNode: 'function (FORMAT)'
+-[METHOD_NAME] IdentNode: 'FORMAT' {originalText=FORMAT}
\-[EXPR_LIST] sqlNode: 'exprList'
+-[DOT] DotNode:
'pratica0_.data_creazione_pratica'
{propertyName=dataInserimento,dereferenceType=PRIMITIVE,getPropertyPath=dataInserimento,path=generatedalias0.dataInserimento,tableAlias=pratica0_,className=mypackage.Pratica,classAlias=generatedalias0}
| +-[ALIAS_REF] IdentNode: 'pratica0_.id_pratica' {alias=generatedalias0,className=it.poste.ristoratori.ministero.application.entity.Pratica,tableAlias=pratica0_}
| \-[IDENT] IdentNode: 'dataInserimento' {originalText=dataInserimento}
\-[QUOTED_STRING] LiteralNode: ''dd/MM/yyyy''
[select function('FORMAT',generatedalias0.dataInserimento,'dd/MM/yyyy')
from mypackage.Pratica as generatedalias0];
nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException:
No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: 'function (FORMAT)'
+-[METHOD_NAME] IdentNode: 'FORMAT' {originalText=FORMAT}
\-[EXPR_LIST] sqlNode: 'exprList'
+-[DOT] DotNode: 'pratica0_.data_creazione_pratica' {propertyName=dataInserimento,classAlias=generatedalias0}
| +-[ALIAS_REF] IdentNode: 'pratica0_.id_pratica'
{alias=generatedalias0,tableAlias=pratica0_}
| \-[IDENT] IdentNode: 'dataInserimento' {originalText=dataInserimento}
\-[QUOTED_STRING] LiteralNode: ''dd/MM/yyyy''
[select function('FORMAT','dd/MM/yyyy')
from mypackage.Pratica as generatedalias0]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
解决方法
这个解决方案对我有用
从 Hibernate 5.2.18 开始,即使您通过 JPA 引导,也可以使用 MetadataBuilderContributor 实用程序来自定义 MetadataBuilder。
MetadataBuilderContributor
接口可以这样实现:
public class SqlFunctionsMetadataBuilderContributor
implements MetadataBuilderContributor {
@Override
public void contribute(MetadataBuilder metadataBuilder) {
metadataBuilder.applySqlFunction(
"group_concat",new StandardSQLFunction(
"group_concat",StandardBasicTypes.STRING
)
);
}
}
而且,我们可以通过 hibernate.metadata_builder_contributor 配置属性提供 SqlFunctionsMetadataBuilderContributor:
<property>
name="hibernate.metadata_builder_contributor"
value="com.vladmihalcea.book.hpjp.hibernate.query.function.SqlFunctionsMetadataBuilderContributor"
</property>
参考:https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/