2017-12-19 4 views
3

호출을 설정하여 GROUP_BY에 사용 된 테스트 결과 목록 ids의 ID를 검색하려고합니다. 나는 이것을 createNativeQuery을 사용하여 작동시킬 수는 있지만, FUNCTION 호출을 사용하여 Spring의 JPA을 사용하여 작동시키지 못했습니다.Spring JPA를 사용하여 STRING_AGG에 대해 Postgresql for Group_By에 대한 집계 함수 설정

저는 스프링 부트 1.4, hibernate 및 PostgreSQL을 사용하고 있습니다.

질문

  1. 사람이 설치가 훨씬 이해할 수있을 것이다 JPA 예에서 다음과 같이 적절한 함수 호출 에 저를 도와주세요 할 수 있습니다.

사용자 정의는이 long에 기능을 캐스팅하려고 것 같습니다 방언 구현 후 업데이트 1

. 기능 코드가 맞습니까? 당신이 그렇지 않으면이 long에 기본값으로 함수의 반환 유형을 등록해야처럼

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

방언을 조사 후 업데이트 2

더 같습니다. 솔루션을 보려면 아래를 참조하십시오.

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

저장소 기능 를 사용하려고

@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); 
작동하지 : 여기

내 코드입니다

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 를 사용

저장소 내가 마지막에 새로운 클래스를 생성하여 함수를 정의되었다 된 주요 부분에서 기능

  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

이 기능은 오타'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")); 
     } 
    } 

다른 문제

필요한 타입 등록의 함수의 리턴 타입 설정하는 것이었다. long을 다시 얻었습니다. registerFunction은 string_agg가 postgres에서 sql 쿼리의 문자열을 반환하더라도 long을 반환하기 때문입니다.

업데이트 후 new org.hibernate.type.StringType()으로 업데이트했습니다.

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