Skip to content

SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 #25399

@rmartseniuk

Description

@rmartseniuk

Affects: <5.2.5.RELEASE>

We use Spring Boot 2.2.6.RELEASE, which includes jdbc driver PostgreSQL version 42.2.11.

We use SimpleJdbcCall for calling stored function in PostgreSQL database version 11.1.

But when we called stored function, we got InvalidDataAccessApiUsageException with message Unable to determine the correct call signature - no procedure/function/signature for 'set_application_variables'.

I looked under the hood and saw that at the stage compile stored function and gather meta information for it, we call PgDatabaseMetaData.getProcedures(String catalog, String schemaPattern, String procedureNamePattern).
In the version 42.2.11 PostgreSQL jdbc driver was added verification for returning only procedures.

public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
      throws SQLException {
    ...
    if (connection.haveMinimumServerVersion(ServerVersion.v11)) {  //check version of database
      sql += " AND p.prokind='p'"; //check that it is stored procedure
    }
   ...

Class where we call stored function.

    @PostConstruct
    private void init() {
        this.jdbcCallStoredProcedure = new SimpleJdbcCall(dataSource)
                .withSchemaName(SCHEMA_NAME)
                .withFunctionName(STORED_FUNCTION_NAME)
                .declareParameters(
                        new SqlParameter(APP_IGNORE_AUDIT, Types.BOOLEAN),
                        new SqlParameter(APP_USERNAME, Types.VARCHAR),
                        new SqlParameter(APP_TRACE_ID, Types.VARCHAR));
    }

    public void save(AuditInfo auditInfo) {
        try {
            SqlParameterSource procedureParameters = new MapSqlParameterSource()
                    .addValue(APP_IGNORE_AUDIT, auditInfo.isIgnoreAudit())
                    .addValue(APP_USERNAME, auditInfo.getUserName())
                    .addValue(APP_TRACE_ID, auditInfo.getTraceId());
            jdbcCallStoredProcedure.executeFunction(Void.class, procedureParameters);
        } catch (RuntimeException e) {
            log.error("Cannot call stored procedure - set_application_variables which sets transaction variable" +
                    " for passing application parameters to audit table in the database.", e);
        }
    }

Stored function.

create or replace function vg_common_db_audit.set_application_variables(app_ignore_audit boolean, app_username text, app_trace_id text) returns void as $body$
                begin
                    --some logic
                end;
$body$ language plpgsql;

Workaround: as workaround we turned off verification meta data via JDBC with method withoutProcedureColumnMetaDataAccess() in SimpleJdbcCall.

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions