使用Spring +调用Postgres存储过程没有为参数指定值

时间:2015-09-14 20:06:01

标签: java spring postgresql stored-procedures spring-jdbc

我在PostgresSql中定义了一个存储过程,如下所示:

CREATE OR REPLACE FUNCTION update_points(accountId bigint, points numeric(19,5)) RETURNS void AS $$
...
...
$$ LANGUAGE plpgsql;

我调用以下方法来调用该过程:

public void updatePoints(final Account account, final BigDecimal points) {
    SimpleJdbcCall simpleCall = new SimpleJdbcCall(coreJdbcTemplate).withFunctionName("update_points");
    SqlParameterSource inputs = new MapSqlParameterSource()
        .addValue("accountId", account.getId())
        .addValue("points", points);                
    simpleCall.execute(inputs);
}

当调用该方法时,我得到以下弹簧错误:

org.springframework.dao.DataIntegrityViolationException: CallableStatementCallback; SQL [{? = call update_points()}]; No value specified for parameter 1.; nested exception is org.postgresql.util.PSQLException: No value specified for parameter 1.
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:102)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1137)
    at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1173)
    at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:388)
    at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:348)
    at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:190)
    at net.exchangesolutions.veo.dao.AccountTransactionDaoImpl.updateRewardsConsumedAmount(AccountTransactionDaoImpl.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)

我尝试了另一种方法用CallableStatement调用该过程,在这种情况下根本不调用该函数。 您知道代码有什么问题,或者您对如何从SpringJPA调用该过程有任何建议吗?

谢谢!

修改 这是我用CallableStatement调用的方式:

public void updatePoints(final Account account, final BigDecimal points) {
        Connection connection;
        try {
            connection = coreJdbcTemplate.getDataSource().getConnection();
            CallableStatement callableSt = connection.prepareCall("{call update_points(?, ?)}");
            callableSt.setLong(1, account.getId());
            callableSt.setBigDecimal(2, points);        
            callableSt.executeUpdate();
        } catch (SQLException e) {

        }
    }

1 个答案:

答案 0 :(得分:0)

我使用以下方法解决了这个问题。我无法弄清楚为什么上述两种方法都不起作用。无论如何,以下解决方案现在正在运作。

public void updatePoints(final Account account,
            final BigDecimal points) {
        coreJdbcTemplate.execute(new CallableStatementCreator() {
            public CallableStatement createCallableStatement(Connection con)
                    throws SQLException {
                CallableStatement cs = con
                        .prepareCall("{call update_points(?, ?)}");
                cs.setLong(1, account.getId());
                cs.setBigDecimal(2, points);
                return cs;
            }
        }, new CallableStatementCallback() {
            public Object doInCallableStatement(CallableStatement cs)
                    throws SQLException {
                cs.execute();

                return null;
            }
        });
相关问题