JPA - 可以在不提供可选参数的情况下调用存储过程吗?

时间:2016-10-07 19:18:20

标签: java hibernate jpa stored-procedures spring-data-jpa

我正在使用许多可选参数调用第三方存储过程。它位于MS SQL Server 2008 R2中,如下所示:

procedure [dbo].[pTest]
    @ReportDate varbinary(max) out, 
    @Optional1 varchar(max) = null,
    @Optional2 varbinary(max) = null,
    @Date varchar(max) = null,
    -- ~20 more optional params of various types 
as
begin
select * from test
end

我使用Spring Data JPA 1.10.2和com.microsoft.sqlserver的sqljdbc 4.2从java调用它。

我只想用两个参数ReportDate和Date来调用该过程。其余的参数可以保持默认值(即null)。我的代码如下:

@Entity
@NamedStoredProcedureQuery(name = "Test.get", procedureName = "pTest", parameters = {
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "ReportData", type = byte[].class),          
@StoredProcedureParameter(mode = ParameterMode.IN, name = "Date", type = String.class)

          })
public class Test {

    // serves no purpose other than to meet
    // JPA requirement
    @Id
    private byte[] reportData;
}

Spring数据存储库:

public interface TestRepository  extends Repository<Test, Long> {
    @Procedure("pTest")
    byte[] get(@Param("Date") String date);
}

测试代码:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional(transactionManager="transactionManager")
public class TestRepositoryTest {

    @Autowired
    private TestRepository testRepository;

    @Test
    public void testGet() throws SQLException {

        byte[] blob = testRepository.get("hi");
        //error occurs
    }

}

我收到以下错误:

   o.h.engine.jdbc.spi.SqlExceptionHelper   : Error preparing CallableStatement [pTest]

com.microsoft.sqlserver.jdbc.SQLServerException: The index 4 is out of range.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:191) ~[sqljdbc-4.2.jar:na]

我得到这个是因为我没有指定Optional1和Optional2。现在,如果我将Optional1和Optional2添加为@StoredProcedureParameter并作为TestRepository的getTest方法的参数,我不再收到错误。但是,我必须传入一个非空的值,否则我会得到另一个错误,抱怨我没有传递任何值。

如何在不指定Optional1和Optional2的情况下优先调用此存储过程?

在某些情况下,我需要调用一个存储过程,其中第15个参数是我需要设置的。我真的不想在我的代码中定义其他14个参数。即使我这样做,我也不能将它们设置为null。

1 个答案:

答案 0 :(得分:0)

使用Microsoft的JDBC驱动程序是不可能的。两个选项:

  1. 使用jTDS(如果存储过程返回&gt; 8000字节,则不是选项)
  2. 创建一个包装器存储过程,该过程只包含所需的参数并让它调用另一个存储过程。如果您没有权限在数据库上创建存储过程,则可能无法选择此项。
  3. 在我的情况下,选项2有效,因为我有权创建存储过程。