Skip to content

Add MySQL/MariaDB to TableMetaDataProviderFactory for correct generated-keys support #35593

@sunwon12

Description

@sunwon12

Summary

TableMetaDataProviderFactory in Spring Framework 6.1.x (used by Spring Boot 3.2.0) lacks a dedicated branch for MySQL and MariaDB. As a result, MySQL connections fall back to GenericTableMetaDataProvider, which incorrectly reports generatedKeysColumnNameArraySupported = true. However, MySQL Connector/J does not actually support specifying column names or indices for generated key retrieval - it only accepts these parameters to comply with JDBC API specifications but ignores them entirely.

Evidence from MySQL Connector/J Source Code

Analysis of StatementImpl.java from MySQL Connector/J reveals that column name/index arrays are converted to boolean flags and discarded:

Line 699-700: execute(String sql, String[] generatedKeyNames)

public boolean execute(String sql, String[] generatedKeyNames) throws SQLException {
    return executeInternal(sql, generatedKeyNames != null && generatedKeyNames.length > 0);
}

The generatedKeyNames array is converted to a boolean and discarded.

Line 694-696: execute(String sql, int[] generatedKeyIndices)

public boolean execute(String sql, int[] generatedKeyIndices) throws SQLException {
    return executeInternal(sql, generatedKeyIndices != null && generatedKeyIndices.length > 0);
}

The generatedKeyIndices array is also converted to a boolean and discarded.

Line 2335-2337: executeLargeUpdate(String sql, String[] columnNames)

public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
    return executeUpdateInternal(sql, false, columnNames != null && columnNames.length > 0);
}

Same pattern - column names converted to boolean.

Line 2330-2332: executeLargeUpdate(String sql, int[] columnIndexes)

public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
    return executeUpdateInternal(sql, false, columnIndexes != null && columnIndexes.length > 0);
}

Same pattern - column indexes converted to boolean.

Line 737: Only boolean flag stored

this.retrieveGeneratedKeys = returnGeneratedKeys;

Only a boolean flag is stored in executeInternal().

Line 158: Field declaration

protected boolean retrieveGeneratedKeys = false;

The only field related to generated keys is a boolean, not an array of column names or indices.

What This Means

MySQL Connector/J provides these method signatures to comply with JDBC API specifications, but completely ignores the provided column names/indices. When getGeneratedKeys() is called, it always returns all auto-increment columns regardless of what was specified.

Therefore, Spring Framework's MySqlTableMetaDataProvider class correctly sets generatedKeysColumnNameArraySupported = false.

Current Problem

The issue is that while MySqlTableMetaDataProvider exists in Spring Framework with the correct metadata settings, it is never actually used. TableMetaDataProviderFactory does not detect MySQL, causing it to fall back to GenericTableMetaDataProvider, which incorrectly sets generatedKeysColumnNameArraySupported = true.

Expected Behavior

  • TableMetaDataProviderFactory should detect "MySQL" and "MariaDB" (via DatabaseMetaData.getDatabaseProductName())
  • Return MySqlTableMetaDataProvider with correct generatedKeysColumnNameArraySupported = false setting
  • Consistent with how Oracle, PostgreSQL, Derby, and HSQL have dedicated providers

Proposed Fix

In TableMetaDataProviderFactory.createMetaDataProvider(), add:

else if ("MySQL".equals(databaseProductName) || "MariaDB".equals(databaseProductName)) {
    provider = new MySqlTableMetaDataProvider(databaseMetaData);
}

Insert this before the else block that creates GenericTableMetaDataProvider.

Impact

  • Ensures accurate metadata representation for MySQL/MariaDB databases
  • Correctly reflects MySQL Connector/J's actual capabilities (does not support column name arrays for generated keys)
  • Utilizes the existing MySqlTableMetaDataProvider class as intended
  • Maintains consistency with other database-specific provider implementations

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions