java - Spring Boot Data JPA 从存储过程接收多个输出参数

标签 java spring-boot jpa stored-procedures spring-data-jpa

我尝试通过 Spring Boot Data JPA (v2.2.6) 调用具有多个输出参数的存储过程,但收到错误:

DEBUG [http-nio-8080-exec-1] org.hibernate.engine.jdbc.spi.SqlStatementLogger: {call TEST_SP(?,?,?)}
RACE [http-nio-8080-exec-1] org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [DOC_NAME] as [VARCHAR] - [ololo]
ERROR [http-nio-8080-exec-1] org.apache.juli.logging.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: OUT/INOUT parameter not available: DOC_ID; nested exception is java.lang.IllegalArgumentException: OUT/INOUT parameter not available: DOC_ID] with root cause
java.lang.IllegalArgumentException: OUT/INOUT parameter not available: DOC_ID

MS SQL Server 2012 中的存储过程:

CREATE PROCEDURE [dbo].[TEST_SP]
    @DOC_ID bigint output,
    @DOC_GUID nvarchar(255) output,
    @DOC_NAME nvarchar(255)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT @DOC_ID = 6666, @DOC_GUID = @DOC_NAME
END

这是我的实体(与 SP 无关):

@Data
@Entity
@NamedStoredProcedureQuery(name = "SomeEntity.test", procedureName = "TEST_SP", parameters = {
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "DOC_ID", type = Long.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "DOC_GUID", type = String.class),
        @StoredProcedureParameter(mode = ParameterMode.IN, name = "DOC_NAME", type = String.class)
})
@Table(name = "DOCUMENT_DATA")
public class SomeEntity {
    // some variables
}

这是我的存储库:

public interface SomeRepository extends JpaRepository<SomeEntity, Long> {

    @Procedure(name = "SomeEntity.test")
    Map<String, Object> testSp(@Param("DOC_NAME") String docName);
}

我是这样调用它的:

@RestController
public class Controller {

    @Autowired
    SomeRepository repository;

    @GetMapping("test")
    String test() {
        return repository.testSp("ololo").toString();
    }
}

作为示例,我使用了这些链接: https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/domain/sample/User.java#L77 https://github.com/spring-projects/spring-data-jpa/blob/e27933455efa6d1821dea23abd2bbe109b5d59a7/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java#L362

更新:我尝试过 Oracle 11g

CREATE OR REPLACE PROCEDURE test_sp(x OUT INTEGER, y OUT INTEGER) AS
BEGIN
  x := 17; y := 93;
END;


@NamedStoredProcedureQuery(name = "EstatementsDataEntity.test", procedureName = "test_sp", parameters = {
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "x", type = Integer.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "y", type = Integer.class)
})

但收到几乎相同的错误:

java.lang.IllegalArgumentException: OUT/INOUT parameter not available: 1

最佳答案

我找不到带注释的工作解决方案并提交了错误 DATAJPA-1722

但是我可以使用EntityManager解决问题:

@SpringBootTest
class DemoApplicationTests {

    @PersistenceContext
    private EntityManager em;

    @Test
    void callStoredProcedureUsingEntitiManager() {
        StoredProcedureQuery proc = em.createStoredProcedureQuery("test_sp");
        proc.registerStoredProcedureParameter("x", Integer.class, ParameterMode.OUT);
        proc.registerStoredProcedureParameter("y", Integer.class, ParameterMode.OUT);
        proc.execute();
        assertThat(proc.getOutputParameterValue("x")).isEqualTo(17);
        assertThat(proc.getOutputParameterValue("y")).isEqualTo(93);
    }

}

关于java - Spring Boot Data JPA 从存储过程接收多个输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61655464/

相关文章:

java - 媒体播放器给我空指针异常

java - 有没有办法使用 Spring Boot 和 Hibernate 使用 postgres 批量插入具有 UUID 主键的实体?

mysql - 用 JPA/Hibernate 覆盖连接继承外键名称

java - FPGA 的软件优势

java - 如何创建一个共享计时器,在第一次初始化后减少

java - 用 Java 表示十六进制映射

spring-boot - 在 Mac 上使用 Jhipster 和 maven 构建(并成功运行)一个 Jar,但无法在 Ubuntu 上运行

java - spring boot启动时如何渲染多个json文件

java - 在 spring boot schema.sql 文件中执行过程的问题

java - JPA CriteriaBuilder 加入额外的 ON 子句参数(谓词)