英文:
Could not invoke FORMAT function im MSSQL by using JPA criteria
问题
我正在尝试使用JPA标准查询语句来执行这个查询:
我正在尝试使用JPA标准查询语句来执行这个查询:
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]|发生了异常
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,dereferenceType=PRIMITIVE,getPropertyPath=dataInserimento,path=generatedAlias0.dataInserimento,tableAlias=pratica0_,className=mypackage.Pratica,classAlias=generatedAlias0}
| +-[ALIAS_REF] IdentNode: 'pratica0_.id_pratica'
{alias=generatedAlias0, className=mypackage.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]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
英文:
I'm trying to execute this query by using JPA criteria:
I'm trying to execute this query by using JPA criteria:
SELECT format(data_creazione_pratica, 'dd/MM/yyyy')
FROM tcigdbexternal.ristoratori_svil.pratica
... So I wrote this JAVA code:
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")));
... But I obtain this exception:
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,dereferenceType=PRIMITIVE,getPropertyPath=dataInserimento,path=generatedAlias0.dataInserimento,tableAlias=pratica0_,className=mypackage.Pratica,classAlias=generatedAlias0}
| +-[ALIAS_REF] IdentNode: 'pratica0_.id_pratica'
{alias=generatedAlias0, className=mypackage.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]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
答案1
得分: 1
这个解决方案对我有效。
自从 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/
英文:
This solution works for me
Since Hibernate 5.2.18, you can use the MetadataBuilderContributor utility to customize the MetadataBuilder even if you are bootstrapping via JPA.
The MetadataBuilderContributor
interface can be implemented like this:
public class SqlFunctionsMetadataBuilderContributor
implements MetadataBuilderContributor {
@Override
public void contribute(MetadataBuilder metadataBuilder) {
metadataBuilder.applySqlFunction(
"group_concat",
new StandardSQLFunction(
"group_concat",
StandardBasicTypes.STRING
)
);
}
}
And, we can provide the SqlFunctionsMetadataBuilderContributor via the hibernate.metadata_builder_contributor configuration property:
<property>
name="hibernate.metadata_builder_contributor"
value="com.vladmihalcea.book.hpjp.hibernate.query.function.SqlFunctionsMetadataBuilderContributor"
</property>
Reference: https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论