ALM*_*ALM 5 java spring jpa aggregate-functions spring-data-jpa
我正在尝试设置一个repository
调用来ids
检索GROUP_BY
. 我可以使用它来工作createNativeQuery
,但我无法使用 Spring 来使它工作JPA
工作FUNCTION
。
FUNCTION(\'string_agg\', FUNCTION(\'to_char\',r.id, \'999999999999\'), \',\')) as ids\n
Run Code Online (Sandbox Code Playgroud)\n\n我正在使用 Spring Boot 1.4、hibernate 和 PostgreSQL。
\n\n问题
\n\n更新1
\n\n实现自定义方言后,看起来它试图将函数转换为long
. 功能代码是否正确?
FUNCTION(\'string_agg\', FUNCTION(\'to_char\',r.id, \'999999999999\'), \',\'))\n
Run Code Online (Sandbox Code Playgroud)\n\n更新2
\n\n进一步研究方言后,您似乎需要注册函数的返回类型,否则它将默认为long
. 请参阅下面的解决方案。
这是我的代码:
\n\n数据传输组织
\n\n @Data\n @NoArgsConstructor\n @AllArgsConstructor\n public class TestScriptErrorAnalysisDto {\n private String testScriptName;\n private String testScriptVersion;\n private String checkpointName;\n private String actionName;\n private String errorMessage;\n private Long count;\n private String testResultIds;\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n控制器
\n\n@RequestMapping(method = RequestMethod.GET)\n@ResponseBody\npublic ResponseEntity<Set<TestScriptErrorAnalysisDto>> getTestScriptErrorsByExecutionId(@RequestParam("executionId") Long executionId) throws Exception {\n\n return new ResponseEntity<Set<TestScriptErrorAnalysisDto>>(testScriptErrorAnalysisRepository.findTestScriptErrorsByExecutionId(executionId), HttpStatus.OK);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n存储库尝试使用函数不起作用
\n\n @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\'), \',\')) "\n + "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 "\n + "GROUP by r.testScriptName, r.testScriptVersion, c.name, ac.name, ac.errorMessage " + "ORDER by ec desc")\nSet<TestScriptErrorAnalysisDto> findTestScriptErrorsByExecutionId(@Param("executionId") Long executionId);\n
Run Code Online (Sandbox Code Playgroud)\n\n使用 createNativeQuery工作的存储库
\n\n List<Object[]> errorObjects = entityManager.createNativeQuery(\n "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 "\n + "FROM action ac, checkpoint c, test_result r " + "WHERE ac.status = \'Failed\' " + "AND ac.checkpoint_id = c.id "\n + "AND r.id = c.test_result_id " + "AND r.test_run_execution_log_id = ? "\n + "GROUP by r.test_script_name, r.test_script_version, c.name, ac.name, ac.error_message " + "ORDER by ec desc")\n .setParameter(1, test_run_execution_log_id).getResultList();\n\n for (Object[] obj : errorObjects) {\n for (Object ind : obj) {\n log.debug("Value: " + ind.toString());\n log.debug("Value: " + ind.getClass());\n }\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n这是我在 FUNCTION 上找到的文档
\n\n 4.6.17.3 Invocation of Predefined and User-defined Database Functions\n\n 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.\n\n function_invocation::= FUNCTION(function_name {, function_arg}*)\n function_arg ::=\n literal |\n state_valued_path_expression |\n input_parameter |\n scalar_expression\n 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.\n\n The function may be a database-defined function or a user-defined function. The function may be a scalar function or an aggregate function.\n\n Applications that use the function_invocation syntax will not be portable across databases.\n\n Example:\n\n SELECT c\n FROM Customer c\n WHERE FUNCTION(\xe2\x80\x98hasGoodCredit\xe2\x80\x99, c.balance, c.creditLimit)\n
Run Code Online (Sandbox Code Playgroud)\n
最后,缺少的主要部分是通过创建一个新类来扩展 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"));
}
}
Run Code Online (Sandbox Code Playgroud)
另一个问题是注册时需要为函数的返回类型设置类型。我得到了long
回复,因为默认情况下registerFunction
返回 a long
,即使 string_agg 会在 postgres 的 sql 查询中返回一个字符串。
更新后就new org.hibernate.type.StringType()
可以了。
registerFunction("string_agg", new StandardSQLFunction("string_agg", new org.hibernate.type.StringType()));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4917 次 |
最近记录: |