Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
rmartseniuk opened this issue Jul 16, 2020 · 1 comment
Closed
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug
Milestone

Comments

@rmartseniuk
Copy link

rmartseniuk commented Jul 16, 2020

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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 16, 2020
@jhoeller jhoeller changed the title SimpleJdbcCall throws exception InvalidDataAccessApiUsageException SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 Jul 16, 2020
@jhoeller jhoeller self-assigned this Jul 16, 2020
@jhoeller jhoeller added type: bug A general bug in: data Issues in data modules (jdbc, orm, oxm, tx) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jul 16, 2020
@jhoeller jhoeller added this to the 5.2.8 milestone Jul 16, 2020
@jhoeller
Copy link
Contributor

This is arguably a breaking change mid-way in the PostgreSQL driver, but given that they're unlikely to revert it and that JDBC 4 did indeed introduce a distinction between procedures and functions, I've revised our GenericCallMetaDataProvider implementation: It explicitly checks DatabaseMetaData.getFunctions as well and correspondingly builds metadata from DatabaseMetaData.getFunctionColumns, provided that DatabaseMetaData.getProcedures did not return a match initially.

I suppose this addresses your scenario. Please test it against the upcoming Spring Framework 5.2.8 snapshot once committed.

FelixFly pushed a commit to FelixFly/spring-framework that referenced this issue Aug 16, 2020
sbesson added a commit to ome/omero-model that referenced this issue Mar 27, 2024
…meter metadata

Version 42.2.11 of the PostgreSQL JDBC driver introduced a backwards-incompatible
change in PgDatabaseMetaData.getProcedures, called internally, to only return
procedures (introduced in PSQL 11).

See spring-projects/spring-framework#25399 for more details
As a workaround, we disable the processing of parameter metadata obtained via JDBC and
explicitly redeclare the function parameters.

This change is the least-invasive requirement in order the upgrade the
org.postgresql:postgresql dependency at the omero-server component.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants