【问题标题】:Could not invoke FORMAT function im MSSQL by using JPA criteria无法使用 JPA 条件在 MYSQL 中调用 FORMAT 函数
【发布时间】:2020-10-14 13:12:55
【问题描述】:

我正在尝试使用 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,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)

【问题讨论】:

  • 就个人而言,我建议不要使用FORMAT,除非您正在处理标量值。 CONVERT 并且样式代码的性能要高得多;特别是对于大型数据集。但是你为什么要把日期改成varchar呢?您的表示层应该定义 display 格式,而不是 SQL Server。
  • 我试过这个criteria.select(criteriaBuilder.function("CONVERT", String.class, root.get("dataInserimento"), criteriaBuilder.literal("103")));但没有成功:你能用JPA Criteria写一个例子吗?

标签: java sql-server jpa criteria


【解决方案1】:

这个解决方案适合我

从 Hibernate 5.2.18 开始,您可以使用 MetadataBuilderContributor 实用程序自定义 MetadataBuilder,即使您是通过 JPA 引导。

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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2015-04-28
    • 1970-01-01
    相关资源
    最近更新 更多