Spring Data JPA -语句未返回结果集

ubbxdtey  于 2023-09-29  发布在  Spring
关注(0)|答案(3)|浏览(174)

在我的应用程序中,我有一个模型,它以父/子关系与自身相关。帖子可以具有也是帖子的父级。我写了一个查询来删除目标帖子及其后代。当我在Spring之外执行查询时,它工作得很好。然而,当在Spring中运行它时,查询成功执行,但抛出以下异常:

WARN  SqlExceptionHelper:144 - SQL Error: 0, SQLState: null
ERROR SqlExceptionHelper:146 - The statement did not return a result set.
ERROR [dispatcherServlet]:182 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet] with root cause
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.

我的查询从扩展JpaRepository的接口运行

@Query(value = "WITH ParentTree AS (\n" +
            "  SELECT Parent.post_key,\n" +
            "    1 AS Level\n" +
            "  FROM community_post AS Parent\n" +
            "    WHERE Parent.post_key = ?1\n" +
            "    UNION ALL\n" +
            "      SELECT Child.post_key,\n" +
            "        pt.Level + 1\n" +
            "      FROM community_post AS Child\n" +
            "      INNER JOIN ParentTree AS pt\n" +
            "        ON Child.post_parent = pt.post_key\n" +
            "      WHERE Child.post_parent IS NOT NULL\n" +
            ")\n" +
            "DELETE FROM community_post\n" +
            "  WHERE post_key IN (\n" +
            "      SELECT post_key\n" +
            "      FROM ParentTree\n" +
            "  )", nativeQuery = true)
    void recursiveDelete(long targetKey);
mklgxw1f

mklgxw1f1#

我认为您还需要添加@Modifying注解。请参阅此处的文档。这是因为SQL Delete不返回结果集。
编辑1:
如果您熟悉API,则可以归结为execute(或executeQuery)与executeUpdate。看起来Spring期望用@Query注解的方法将返回一个resultset,所以当它没有返回时,它会感到失望。相关SO问题/答案here

q43xntqr

q43xntqr2#

如果缺少**@Modifying注解,则使用@Query**添加注解。

wwtsj6pe

wwtsj6pe3#

我在使用@Modifying时得到了同样的错误,尽管我使用了使用存储过程的Create查询。
我需要使用@Transactional@Modifying来解决我的问题。
我的代码:

@Modifying
@Transactional
@Query(value = "exec [cmpl].[CreateComplaintHistory] :complaintNumber,:eventType, :eventCreator, " +
            ":deptFrom, :deptTo, :assignedUser ",  nativeQuery = true)

void createComplaintHistory(
        @Param("complaintNumber") String complaintNumber,
        @Param("eventType") String eventType,
        @Param("eventCreator") String eventCreator,
        @Param("deptFrom") String deptFrom,
        @Param("deptTo") String deptTo,
        @Param("assignedUser") String assignedUser
    );

我的存储过程的另一个解决方案
我使用@Procedure注解并删除@Modifying@Transactional
验证码:

@Procedure(procedureName = "cmpl.CreateComplaintHistory")
void createComplaintHistory(@Param("complaintNumber") String complaintNumber,
        @Param("eventType") String eventType,
        @Param("eventCreator") String eventCreator,
        @Param("deptFrom") String deptFrom,
        @Param("deptTo") String deptTo,
        @Param("assignedUser") String assignedUser
    );

相关问题