简体   繁体   English

Spring 引导数据 JPA 从存储过程接收多个输出参数

[英]Spring Boot Data JPA receive Multiple Out Parameters from stored procedure

I'm trying to call stored procedure with multiple out parameters via Spring Boot Data JPA (v2.2.6), but receive an error:我正在尝试通过 Spring 引导数据 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

Stored procedure in MS SQL Server 2012: 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

Here my entity (it is not related to SP):这是我的实体(它与 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
}

Here my repository:这是我的存储库:

public interface SomeRepository extends JpaRepository<SomeEntity, Long> {

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

Here how I call it:这里我怎么称呼它:

@RestController
public class Controller {

    @Autowired
    SomeRepository repository;

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

As example I used these links: 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例如,我使用了这些链接: 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#L36

Upd: I've tried with Oracle 11g更新:我试过 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)
})

But receive almost identical error:但收到几乎相同的错误:

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

I could not find working solution with annotations and submitted a bug DATAJPA-1722我找不到带有注释的工作解决方案并提交了错误DATAJPA-1722

But I could managed to solve issue using EntityManager :但我可以设法使用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);
    }

}

FYI for anyone still using older versions of Spring Boot.仅供仍在使用旧版本 Spring 引导的任何人使用。 This error was caused by calling a procedure without enclosing it in a transaction.此错误是由调用过程而不将其包含在事务中引起的。 Error message was a bit of a red herring but the fix was to add @Transaction to the caller.错误消息有点像红鲱鱼,但解决方法是将@Transaction 添加到调用者。

In the example above I'd include a service layer class between Controller and SomeRepository and annotate my service layer method as transactional.在上面的示例中,我将在 Controller 和 SomeRepository 之间包含一个服务层 class 并将我的服务层方法注释为事务性的。

ie IE

@Service
public class SomeService{
    
    @Autowired
    SomeRepository someRepo;

    @Transactional
    public Map<String, Object> testSp(String docName){
        return someRepo.testSp(docName);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring数据jpa调用带有大量参数的存储过程 - Spring data jpa calling stored procedure with lots of parameters Spring Data JPA NamedStoredProcedureQuery 多个输出参数 - Spring Data JPA NamedStoredProcedureQuery Multiple Out Parameters Spring 数据 JPA map 存储过程结果从多个数据源到非实体 POJO - Spring Data JPA map the stored procedure result to Non-Entity POJO from multiple data source 带有多个输出参数的 JPA 2.1 @Procedure - JPA 2.1 @Procedure with multiple out parameters 如何使用JPA和Hibernate调用具有多个OUT参数的MySQL存储过程? - How to call a MySQL stored procedure with multiple OUT parameters using JPA and Hibernate? 使用 OUT 参数调用存储过程 Spring Spring JPA 2.* - Calling stored procedure using OUT parameter with Spring Spring JPA 2.* 如何通过Spring Boot使用JPA的crudrepository执行存储过程?[PropertyReferenceException] - How to execute a stored procedure with JPA's crudrepository with Spring boot?[PropertyReferenceException] 如何从Spring Jdbc中的存储过程中读取返回的值(过程中没有参数) - How read returned value from stored procedure in Spring Jdbc (without out parameters in procedure) 尝试使用 Spring Data JPA 运行存储过程时,“类型不能为空”异常 - `Type cannot be null` exception when trying to run out Stored Procedure using Spring Data JPA Spring Boot,带有多个数据源的Spring Data JPA - Spring Boot, Spring Data JPA with multiple DataSources
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM