【问题标题】:JPA Criteria API group_concat usageJPA Criteria API group_concat 用法
【发布时间】:2014-02-19 15:01:45
【问题描述】:

我目前正在编写一份报告,其中一个字段需要 group_concat。

CriteriaQuery<GameDetailsDto> criteriaQuery = criteriaBuilder
                .createQuery(GameDetailsDto.class);
Root<BetDetails> betDetails = criteriaQuery.from(BetDetails.class);
Expression<String> betSelection = betDetails.get("winningOutcome");
criteriaQuery.multiselect(
    // other fields to select
    criteriaBuilder.function("group_concat", String.class, betSelection),
    // other fields to select
    );
//predicate, where clause and other filters

TypedQuery<GameDetailsDto> typedQuery = entityManager.createQuery(criteriaQuery);

这会在该行引发空指针异常:

TypedQuery<GameDetailsDto> typedQuery = entityManager.createQuery(criteriaQuery);

我是不是错误地使用了criteriaBuilder的函数方法?
文件说:

function(String name, Class<T> type, Expression<?>... args);

【问题讨论】:

  • 包括空指针的堆栈跟踪。

标签: jpa group-concat


【解决方案1】:

我想出了如何使用 Hibernate-jpa-mysql 做到这一点:

1.) 创建了一个扩展 org.hibernate.dialect.function.SQLFunction 的 GroupConcatFunction 类(目前仅用于单列 group_concat)

public class GroupConcatFunction implements SQLFunction {

@Override
public boolean hasArguments() {
    return true;
}

@Override
public boolean hasParenthesesIfNoArguments() {
    return true;
}

@Override
public Type getReturnType(Type firstArgumentType, Mapping mapping)
        throws QueryException {
    return StandardBasicTypes.STRING;
}

@Override
public String render(Type firstArgumentType, List arguments,
        SessionFactoryImplementor factory) throws QueryException {
    if (arguments.size() != 1) {
        throw new QueryException(new IllegalArgumentException(
                "group_concat shoudl have one arg"));
    }
    return "group_concat(" + arguments.get(0) + ")";
}

}


2.) 我创建了扩展 org.hibernate.dialect.MySQL5Dialect 的 CustomMySql5Dialect 类,并注册了在步骤 1 中创建的 group_concat 类
3.) 在应用程序上下文中,我更新了 jpaVendorAdapter 以使用 CustomMySql5Dialect 作为数据库平台
4.) 最后使用它

criteriaBuilder.function("group_concat", String.class,
        sampleRoot.get("sampleColumnName"))

【讨论】:

    【解决方案2】:

    简单的解决方案:不用创建整个类,只需使用SQLFunctionTemplate

    new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)")
    

    然后在你自己的 SQL 方言中注册这个函数(例如在构造函数中)

    public class MyOwnSQLDialect extends MySQL5Dialect {
    
      public MyOwnSQLDialect() {
        super();
        this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)"));
      }
    }
    

    【讨论】:

      【解决方案3】:

      建议的属性:

      spring.jpa.properties.hibernate.metadata_builder_contributor = com.inn.core.generic.utils.SqlFunctionsMetadataBuilderContributor
      

      和类:

      import org.hibernate.boot.MetadataBuilder;
      import org.hibernate.boot.spi.MetadataBuilderContributor;
      import org.hibernate.dialect.function.StandardSQLFunction;
      import org.hibernate.type.StandardBasicTypes;
      import org.springframework.stereotype.Component;
      @Component
      public class SqlFunctionsMetadataBuilderContributor implements MetadataBuilderContributor {
      
          @Override
          public void contribute(MetadataBuilder metadataBuilder) {
              metadataBuilder.applySqlFunction("config_json_extract",
                      new StandardSQLFunction("json_extract", StandardBasicTypes.STRING));
              metadataBuilder.applySqlFunction("JSON_UNQUOTE",
                      new StandardSQLFunction("JSON_UNQUOTE", StandardBasicTypes.STRING));
              metadataBuilder.applySqlFunction("group_concat", 
                      new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
      
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-21
        • 1970-01-01
        • 2011-04-30
        • 2018-12-24
        • 2023-03-15
        • 1970-01-01
        • 2015-02-15
        • 2018-07-04
        相关资源
        最近更新 更多