2017-12-19 27 views
3

コールを設定して、GROUP_BYで使用されるテスト結果のリストidsのIDを取得しようとしています。私はcreateNativeQueryを使ってこれを動作させることができますが、これはFUNCTION呼び出しでSpringのJPAを使って動作させることができません。Spring JPAを使用してSTRING_AGGに集計関数を設定し、Group_ByのためにPostgresqlを使用する

私は、Springブート1.4、hibernateとPostgreSQLを使用しています。

質問

  1. 誰かがセットアップそれははるかに高く評価されるだろうJPAの例では、以下に示す適切な関数呼び出し に私を助けてくださいすることができます。

アップデート1

それはそのがlongに関数をキャストしようとしているように見える独自の方言を実装した後。ファンクションコードは正しいですか?

FUNCTION('string_agg', FUNCTION('to_char',r.id, '999999999999'), ',')) 

アップデート2

さらに、それはあなたがあなたの関数の戻り値の型を登録する必要がありますように、それ以外の場合はlongがデフォルトになります見え方言に見た後。ソリューションについては以下を参照してください。

ここは私のコードです:

@Query(value = "SELECT new com.dto.TestScriptErrorAnalysisDto(r.testScriptName, r.testScriptVersion, c.name, ac.name, ac.errorMessage, count(*) as ec, FUNCTION('string_agg', FUNCTION('to_char',r.id, '999999999999'), ',')) " 
    + "FROM Action ac, Checkpoint c, TestResult r " + "WHERE ac.status = 'Failed' " + "AND ac.checkpoint = c.id " + "AND r.id = c.testResult " + "AND r.testRunExecutionLogId = :executionId " 
    + "GROUP by r.testScriptName, r.testScriptVersion, c.name, ac.name, ac.errorMessage " + "ORDER by ec desc") 
Set<TestScriptErrorAnalysisDto> findTestScriptErrorsByExecutionId(@Param("executionId") Long executionId); 
を働いていない機能 を使用しようとして

DTO

@Data 
    @NoArgsConstructor 
    @AllArgsConstructor 
    public class TestScriptErrorAnalysisDto { 
     private String testScriptName; 
     private String testScriptVersion; 
     private String checkpointName; 
     private String actionName; 
     private String errorMessage; 
     private Long count; 
     private String testResultIds; 
    } 

コントローラ

@RequestMapping(method = RequestMethod.GET) 
@ResponseBody 
public ResponseEntity<Set<TestScriptErrorAnalysisDto>> getTestScriptErrorsByExecutionId(@RequestParam("executionId") Long executionId) throws Exception { 

    return new ResponseEntity<Set<TestScriptErrorAnalysisDto>>(testScriptErrorAnalysisRepository.findTestScriptErrorsByExecutionId(executionId), HttpStatus.OK); 
} 

リポジトリ

List<Object[]> errorObjects = entityManager.createNativeQuery(
      "SELECT r.test_script_name, r.test_script_version, c.name as checkpoint_name, ac.name as action_name, ac.error_message, count(*) as ec, string_agg(to_char(r.id, '999999999999'), ',') as test_result_ids " 
        + "FROM action ac, checkpoint c, test_result r " + "WHERE ac.status = 'Failed' " + "AND ac.checkpoint_id = c.id " 
        + "AND r.id = c.test_result_id " + "AND r.test_run_execution_log_id = ? " 
        + "GROUP by r.test_script_name, r.test_script_version, c.name, ac.name, ac.error_message " + "ORDER by ec desc") 
    .setParameter(1, test_run_execution_log_id).getResultList(); 

    for (Object[] obj : errorObjects) { 
     for (Object ind : obj) { 
      log.debug("Value: " + ind.toString()); 
      log.debug("Value: " + ind.getClass()); 
     } 
    } 

ここで働いてcreateNativeQuery を使用して

リポジトリは、私が最後に新しいクラスを作成することにより、関数を定義して行方不明になった主な作品にはFUNCTION

  4.6.17.3 Invocation of Predefined and User-defined Database Functions 

    The invocation of functions other than the built-in functions of the Java Persistence query language is supported by means of the function_invocation syntax. This includes the invocation of predefined database functions and user-defined database functions. 

    function_invocation::= FUNCTION(function_name {, function_arg}*) 
    function_arg ::= 
      literal | 
      state_valued_path_expression | 
      input_parameter | 
      scalar_expression 
    The function_name argument is a string that denotes the database function that is to be invoked. The arguments must be suitable for the database function that is to be invoked. The result of the function must be suitable for the invocation context. 

    The function may be a database-defined function or a user-defined function. The function may be a scalar function or an aggregate function. 

    Applications that use the function_invocation syntax will not be portable across databases. 

    Example: 

    SELECT c 
    FROM Customer c 
    WHERE FUNCTION(‘hasGoodCredit’, c.balance, c.creditLimit) 
+0

これはtypo 'FUNCTION( 'to_char'、r.id、 '999999999999')、 '、'))' ?? –

+0

@JorgeCamposはい、それを更新しましたが、まだ動作していないようです。 – ALM

+0

"動作しません"。これは意味するところは、 – DN1

答えて

0

で見つかった文書でしたPostgreSQL94Dialectを拡張します。これらの関数は方言用に定義されていないので、呼び出しでは処理されませんでした。

public class MCBPostgreSQL9Dialect extends PostgreSQL94Dialect { 

     public MCBPostgreSQL9Dialect() { 
      super(); 
      registerFunction("string_agg", new StandardSQLFunction("string_agg", new org.hibernate.type.StringType())); 
      registerFunction("to_char", new StandardSQLFunction("to_char")); 
      registerFunction("trim", new StandardSQLFunction("trim")); 
     } 
    } 

もう1つの問題は、登録時に関数の戻り値の型に設定する必要があるということでした。私はlongを元に戻しました。registerFunctionは、string_aggがpostgresのSQLクエリで文字列を返しても、longを返します。

new org.hibernate.type.StringType()でそれを更新した後、それは働いた。

  registerFunction("string_agg", new StandardSQLFunction("string_agg", new org.hibernate.type.StringType()));