org.postgresql.util.PSQLException:错误:运算符不存在:integer = bytea

时间:2019-10-08 05:22:00

标签: java postgresql hibernate spring-boot spring-data-jpa

我正在尝试从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

2 个答案:

答案 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();

    }

如果提供更好的解决方案,我将竭诚欢迎