无法通过使用JPA criteria在MSSQL中调用FORMAT函数。

huangapple go评论78阅读模式
英文:

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, &#39;dd/MM/yyyy&#39;)
FROM tcigdbexternal.ristoratori_svil.pratica

... So I wrote this JAVA code:

final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();                  
final CriteriaQuery&lt;String&gt; criteria = criteriaBuilder.createQuery(String.class);            
final Root&lt;Pratica&gt; root = criteria.from(Pratica.class);                                     
criteria.select(criteriaBuilder.function(&quot;FORMAT&quot;, String.class, root.get(&quot;dataInserimento&quot;),
		criteriaBuilder.literal(&quot;dd/MM/yyyy&quot;)));                                             

... 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: &#39;function (FORMAT)&#39;      
		+-[METHOD_NAME] IdentNode: &#39;FORMAT&#39; {originalText=FORMAT}      
			\-[EXPR_LIST] SqlNode: &#39;exprList&#39;         
				+-[DOT] DotNode: 
					&#39;pratica0_.data_creazione_pratica&#39; 
					{propertyName=dataInserimento,dereferenceType=PRIMITIVE,getPropertyPath=dataInserimento,path=generatedAlias0.dataInserimento,tableAlias=pratica0_,className=mypackage.Pratica,classAlias=generatedAlias0}
					|  +-[ALIAS_REF] IdentNode: &#39;pratica0_.id_pratica&#39; {alias=generatedAlias0, className=it.poste.ristoratori.ministero.application.entity.Pratica, tableAlias=pratica0_} 
					|  \-[IDENT] IdentNode: &#39;dataInserimento&#39; {originalText=dataInserimento}
			\-[QUOTED_STRING] LiteralNode: &#39;&#39;dd/MM/yyyy&#39;&#39;
					[select function(&#39;FORMAT&#39;, generatedAlias0.dataInserimento, &#39;dd/MM/yyyy&#39;)
					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: &#39;function (FORMAT)&#39;
				+-[METHOD_NAME] IdentNode: &#39;FORMAT&#39; {originalText=FORMAT}
					\-[EXPR_LIST] SqlNode: &#39;exprList&#39;
					+-[DOT] DotNode: &#39;pratica0_.data_creazione_pratica&#39; {propertyName=dataInserimento,dereferenceType=PRIMITIVE,getPropertyPath=dataInserimento,path=generatedAlias0.dataInserimento,tableAlias=pratica0_,className=mypackage.Pratica,classAlias=generatedAlias0}
					|  +-[ALIAS_REF] IdentNode: &#39;pratica0_.id_pratica&#39;
					{alias=generatedAlias0, className=mypackage.Pratica, tableAlias=pratica0_}
					|  \-[IDENT] IdentNode: &#39;dataInserimento&#39; {originalText=dataInserimento}
					\-[QUOTED_STRING] LiteralNode: &#39;&#39;dd/MM/yyyy&#39;&#39;
					[select function(&#39;FORMAT&#39;, generatedAlias0.dataInserimento, &#39;dd/MM/yyyy&#39;)
					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(
        &quot;group_concat&quot;,
        new StandardSQLFunction(
            &quot;group_concat&quot;,
            StandardBasicTypes.STRING
        )
    );
 }
}

And, we can provide the SqlFunctionsMetadataBuilderContributor via the hibernate.metadata_builder_contributor configuration property:

&lt;property&gt;
    name=&quot;hibernate.metadata_builder_contributor&quot;
    value=&quot;com.vladmihalcea.book.hpjp.hibernate.query.function.SqlFunctionsMetadataBuilderContributor&quot;
&lt;/property&gt;

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

huangapple
  • 本文由 发表于 2020年10月14日 21:12:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/64354087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定