2011-08-10 15 views
2

現在、フィールドの1つにgroup_concatが必要なレポートを作成しています。JPA Criteria API group_concat usage

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); 

これはライン上でnullポインタ例外がスローされます。

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

私が間違ってcriteriaBuilderの機能メソッドを使用しましたか?
ドキュメンテーションは言います:

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

はNULLポインタのスタックトレースを含めます。 – James

答えて

7

私は休止状態-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.)iはorg.hibernate.dialect.MySQL5Dialect延びるCustomMySql5Dialectクラスを作成し、アプリケーションのコンテキストに
3ステップ1で作成したGROUP_CONCATクラス)を登録し、私のDatabasePlatform としてCustomMySql5Dialectを使用するjpaVendorAdapterを更新します
4)最後に

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

簡単な解決策それを使用する:全体ではなくクラスを作成するのではなく、単に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)")); 
    } 
}