SimpleJdbcCall 在 windows 中有效,但在 linux 中无效

SimpleJdbcCall works in windows but not linux

我有一个 spring 引导应用程序,我在其中使用 SimpleJdbcCall 执行存储过程,在 Windows (jdk1.8.0_111) 中一切正常,但是当我尝试运行 它在 Linux 服务器上(使用 java 1.8.0_131)它抛出错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect number of arguments for PROCEDURE banco.spcon_sesion; expected 18, got 0

这是我的代码:

@Override
public Usuario sesion(Credenciales credenciales) {

        SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
            .withProcedureName("spcon_sesion")
            .declareParameters(new SqlParameter("in_usuario", Types.CHAR))
            .declareParameters(new SqlParameter("in_contrasena", Types.CHAR))
            .declareParameters(new SqlParameter("in_idSistema", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_idUsuario", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombre", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_paterno", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_materno", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idPerfil", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombrePerfil", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idComercio", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombreComercio", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idTerminal", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombreTerminal", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idSucursal", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_referenciaRetiroEfectivo", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idProveedorSucursal", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_codigo", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_mensaje", Types.CHAR));

        SqlParameterSource in = new MapSqlParameterSource()
            .addValue("in_usuario", credenciales.getUsuario())
            .addValue("in_contrasena", credenciales.getContrasena())
            .addValue("in_idSistema", credenciales.getIdSistema());

        Map<String, Object> result = jdbcCall.execute(in);

        @SuppressWarnings("unchecked")
        List<Menu> menus = Menu
                .obtenerListaMenus((List<Map<String, Object>>) result.get("#result-set-1"));

        String codigo = (String) result.get("out_codigo");
        if (codigo != null && codigo.equals("00")) {
            try {

                return new Usuario(
                    Util.ifNullToLong(result.get("out_idUsuario"), 0L),
                    Util.ifNullToString(result.get("out_nombre"), ""),
                    Util.ifNullToString(result.get("out_paterno"), ""),
                    Util.ifNullToString(result.get("out_materno"), ""),
                    Util.ifNullToString(result.get("out_referenciaRetiroEfectivo"), ""),
                    Util.ifNullToLong(result.get("out_idComercio"), 0L),
                    Util.ifNullToString(result.get("out_nombreComercio"), ""),
                    Util.ifNullToLong(result.get("out_idTerminal"), 0L),
                    Util.ifNullToString(result.get("out_nombreTerminal"), ""),
                    Util.ifNullToLong(result.get("out_idPerfil"), 0L),
                    Util.ifNullToString(result.get("out_nombrePerfil"), ""),
                    Util.ifNullToLong(result.get("out_idSucursal"), 0L),
                    Util.ifNullToLong(result.get("out_idProveedorSucursal"), 0L),
                    menus
                );

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;

    }

我也尝试使用带有 openjdk8 的 docker 容器并出现同样的错误,有人可以帮我解决这个问题吗?

您似乎遇到了区分大小写的问题(在某些情况下,Win 和 MacOS 会忽略标识符的大小写)。按照 documentation.

检查您的设置

首先,尝试删除所有 declareParameters - 不需要它们。

 SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
                               .withProcedureName("spcon_sesion");

 SqlParameterSource in =
     new MapSqlParameterSource()
            .addValue("in_usuario", credenciales.getUsuario())
            .addValue("in_contrasena", credenciales.getContrasena())
            .addValue("in_idSistema", credenciales.getIdSistema());

 Map<String, Object> result = jdbcCall.execute(in);

如果这没有帮助 - 在这段特定的代码中使用纯 callable statement 而不是 SpringBoot 工具来定位问题。最好创建一个参数名称都采用相同大小写(小写或大写)的存储过程并测试其调用。

PS。我想 jdbcTemplate 中可能存在问题(如果可能,请在问题中提供其定义),因此为了简化情况,请考虑使用 new SimpleJdbcCall(dataSource).

我找到了答案,我需要添加

.withoutProcedureColumnMetaDataAccess()

像这样调用 simpleJdbcCall:

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
            .withProcedureName("spcon_sesion")
            .withoutProcedureColumnMetaDataAccess()
            .declareParameters(new SqlParameter("in_usuario", Types.CHAR))
            .declareParameters(new SqlParameter("in_contrasena", Types.CHAR))
            .declareParameters(new SqlParameter("in_idSistema", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_idUsuario", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombre", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_paterno", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_materno", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idPerfil", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombrePerfil", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idComercio", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombreComercio", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idTerminal", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_nombreTerminal", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idSucursal", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_referenciaRetiroEfectivo", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_idProveedorSucursal", Types.INTEGER))
            .declareParameters(new SqlOutParameter("out_codigo", Types.CHAR))
            .declareParameters(new SqlOutParameter("out_mensaje", Types.CHAR));

希望这对某人有所帮助:)