我正在尝试从Spring Boot应用程序执行本机查询,但出现此错误“ org.postgresql.util.PSQLException:错误:运算符不存在:integer = bytea“
这是我为实现此目的而编写的代码
@SqlResultSetMapping(
name = "StudentAssessmentValue",
classes = @ConstructorResult(
targetClass = StudentAssessmentDTO.class,
columns = {
@ColumnResult(name = "subject_title", type = String.class),
@ColumnResult(name = "assessment", type = String.class),
}
)
)
@NamedNativeQuery(
name = "getStudentSubjectsAssessment",
query = "SELECT\n" +
" subject.subject_title,\n" +
" j as assessment\n" +
"FROM assessment s\n" +
"JOIN LATERAL jsonb_array_elements(s.assessment) j(elem) ON (j.elem->>'student_id') = :student_id\n" +
"JOIN subject ON subject.id = s.subject_id\n" +
"WHERE s.subject_id IN (:subjects)\n" +
"AND s.academy_year_id = :academy_year_id\n" +
"AND s.term_id = :term_id\n" +
"AND s.section_id = :section_id"
,
resultSetMapping = "StudentAssessmentValue"
)
这是我的存储库中的代码
@Query(nativeQuery = true, name = "getStudentSubjectsAssessment")
List<StudentAssessmentDTO> getStudentAssessments2(
@Param("student_id") String student_id,
@Param("academy_year_id") Integer academy_year_id,
@Param("section_id") Integer section_id,
@Param("term_id") Integer term_id,
@Param("subjects") Integer[] subjects
);
我在控制器中有这个
@GetMapping("/{student_id}/{academy_year_id}/{section_id}/
term_id}")
public List<StudentAssessmentDTO> getStudentAssessment2(
@PathVariable("student_id") String student_id,
@PathVariable("academy_year_id") Integer academy_year_id,
@PathVariable("section_id") Integer section_id,
@PathVariable("term_id") Integer term_id,
@RequestParam(value = "subjects") Integer[] subjects
){
return assessmentService.getStudentAssessments2(student_id, academy_year_id, section_id, term_id, subjects);
}
我还注意到是否从查询中删除了这部分 在s.subject_id IN(:subjects)那里,或者说我像s.subject_id IN(2,3,4)这样对主题值进行硬编码,代码成功运行。但是,如果值来自请求,那么我会得到错误。这是请求的样子
localhost:8080 / assessment / f3df0bc2-7b4c-49b9-86c9-6e6b01628623 / 3/4/1?subjects = 2,3,4
答案 0 :(得分:1)
我最近有一个similar problem to yours,同时还在Postgres上处理本机JPA查询。这是对我有用的东西:
// sqlString contains your native query
Query query = entityManager.createNativeQuery(sqlString, StudentAssessmentDTO.class);
query.setParameter("subjects", subjects);
query.setParameter("academy_year_id", new TypedParameterValue(IntegerType.INSTANCE, academy_year_id));
query.setParameter("term_id", new TypedParameterValue(IntegerType.INSTANCE, term_id));
query.setParameter("section_id", new TypedParameterValue(IntegerType.INSTANCE, section_id));
List< StudentAssessmentDTO > = query.getResultList();
您看到的错误可以由Postgres JDBC驱动程序无法正确将所需的类型信息传递到数据库来解释。例如,以下错误:
错误:运算符不存在:integer = bytea
会发生,因为驱动程序将参数作为字节数组传递给Postgres,但是目标列是整数类型。通过使用上述类型的“提示”,我们可以强制驱动程序传递正确的类型信息。
答案 1 :(得分:0)
这可能不是最好的解决方案,但是它对我有用,如果有人仍然可以提供更好的解决方案,我将感到高兴。
这就是我所做的:
我编写了一个方法,该方法将从请求中获取数组,并生成具有这种性质的字符串"(a,b,c)"
,然后将该字符串添加到我的查询字符串中并且可以正常工作
代码
这是构建字符串的方法 注意:我可以使用此功能,因为我确定该数组的元素不会快速增长,对于我的情况,最大值为15
public String generateInSearchParameter(Integer[] inputArr){
StringBuilder search = new StringBuilder("(");
IntStream.range(0, inputArr.length).forEach(i -> {
if (i != inputArr.length - 1) {
search.append(inputArr[i]).append(',');
} else {
search.append(inputArr[i]);
}
});
search.append(")");
return search.toString();
}
这是控制器代码
@GetMapping("/{student_id}/{academy_year_id}/{section_id}/{term_id}")
public List<StudentAssessmentDTO> getStudentAssessment2(
@PathVariable("student_id") String student_id,
@PathVariable("academy_year_id") Integer academy_year_id,
@PathVariable("section_id") Integer section_id,
@PathVariable("term_id") Integer term_id,
@RequestParam(value = "subjects") Integer[] subjects
){
return assessmentService.getStudentAssessments2(student_id, academy_year_id, section_id, term_id,generateInSearchParameter(subjects));
}
这是我的服务中的代码
public List<StudentAssessmentDTO> getStudentAssessments2(
String student_id, Integer academy_year_id,
Integer section_id, Integer term_id, String subjects
){
String sqlString = "SELECT" +
" subject.subject_title," +
" j.*" +
" FROM assessment s" +
" JOIN LATERAL jsonb_array_elements(s.assessment) j(elem) ON (j.elem->>'student_id') = :student_id" +
" JOIN subject ON subject.id = s.subject_id" +
" WHERE s.academy_year_id = :academy_year_id" +
" AND s.section_id = :section_id" +
" AND s.subject_id IN " + subjects +
" AND s.term_id = :term_id";
Query query = entityManager.createNativeQuery(sqlString, "StudentAssessmentValue");
query.setParameter("academy_year_id", new TypedParameterValue(IntegerType.INSTANCE, academy_year_id));
query.setParameter("term_id", new TypedParameterValue(IntegerType.INSTANCE, term_id));
query.setParameter("section_id", new TypedParameterValue(IntegerType.INSTANCE, section_id));
query.setParameter("student_id", new TypedParameterValue(StringType.INSTANCE, student_id));
return query.getResultList();
}
如果提供更好的解决方案,我将竭诚欢迎