SpringBoot 1.5.3 createStoredProcedureQuery不接受Null参数

时间:2017-05-08 21:18:50

标签: java sql-server spring hibernate stored-procedures

将SpringBoot与MSSQL服务器存储过程一起使用时,当值为null时,存储过程无法执行。调用时,该值的默认值为null。 如果排除了参数,则proc工作。但由于这些是可选参数,我可以选择调用存储过程吗?

当我尝试在调用存储过程时传递null时,它会因此错误而失败。

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Error calling CallableStatement.getMoreResults; SQL [saveInfo]; nested exception is org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults] with root cause
java.sql.SQLException: Parameter #1 has not been set.
        at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1049)
        at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:563)
        at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.execute(JtdsPreparedStatement.java:787)
        at org.hibernate.result.internal.OutputsImpl.<init>(OutputsImpl.java:52)
        at org.hibernate.procedure.internal.ProcedureOutputsImpl.<init>(ProcedureOutputsImpl.java:32)
        at org.hibernate.procedure.internal.ProcedureCallImpl.buildOutputs(ProcedureCallImpl.java:411)
        at org.hibernate.procedure.internal.ProcedureCallImpl.getOutputs(ProcedureCallImpl.java:363)
        at org.hibernate.jpa.internal.StoredProcedureQueryImpl.outputs(StoredProcedureQueryImpl.java:234)
        at org.hibernate.jpa.internal.StoredProcedureQueryImpl.execute(StoredProcedureQueryImpl.java:217)
        at com.tda.etfmc.service.repository.ETFMgmtRepository.saveCommissionFreeETF(ETFMgmtRepository.java:87)
        at com.tda.etfmc.service.repository.ETFMgmtRepository$$FastClassBySpringCGLIB$$d1d68142.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

StoredProc:

CREATE PROCEDURE [dbo].[saveInfo]  
     @input1                        varchar(16) = NULL,
     @input2                        varchar(16) = NULL
AS  
BEGIN   
//do save here
END  

GO


@Repository
public class MyRepository {
    private EntityManager entityManager;

    public MyRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Procedure(name = "saveInfo")
    @Transactional
    public void saveInfo(List<Input> inputList) throws SQLException {
        StoredProcedureQuery saveInfo;
        for (Input input : inputList) {
            saveInfo = entityManager.createNamedStoredProcedureQuery("saveInfo");
            saveInfo.setParameter("input1", input.getInput1());// pass null here
            saveInfo.setParameter("input2", input.getInput2());
            saveInfo.execute();
        }
    }
}

@Data
@NamedStoredProcedureQuery(name = "saveInfo", procedureName = "saveInfo", parameters = {
        @StoredProcedureParameter(name = "input1", type = String.class, mode = ParameterMode.IN),
        @StoredProcedureParameter(name = "input2", type = String.class, mode = ParameterMode.IN) })
class Input implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "@input1")
    private String input1;

    @Column(name = "@input2")
    private String input2;
}

0 个答案:

没有答案