You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
However, at least on current versions of HSQLDB, the support for column names is present, and even documented
getGeneratedKeys
Starting with version 2.0, HSQLDB supports this feature with single-row and multi-row insert, update and merge statements.
This method returns a result set only if the executeUpdate methods that was used is one of the three methods that have the extra parameter indicating return of generated keys
If the executeUdate method did not specify the columns which represent the auto-generated keys the IDENTITY column or GENERATED column(s) of the table are returned.
The executeUpdate methods with column indexes or column names return the post-insert or post-update values of the specified columns, whether the columns are generated or not. This allows values that have been modified by execution of triggers to be returned.
If column names or indexes provided by the user in the executeUpdate() method calls do not correspond to table columns (incorrect names or indexes larger than the column count), an empty result is returned.
Why does it matter? Because using Statement.RETURN_GENERATED_KEYS will only return columns that are either an IDENTITY or GENERATED column; but a primary key may be generated through a different means. For instance, take this simple table:
CREATETABLEDEMO(
id UUID NOT NULL DEFAULT uuid(),
val VARCHAR(10) NOT NULL,
PRIMARY KEY(id)
);
Given the following SimpleJdbcInsert:
SimpleJdbcInsertjdbcInsert = newSimpleJdbcInsert(ds)
.withTableName("DEMO")
.usingColumns("val")
.usingGeneratedKeyColumns("id");
KeyHolderkeyHolder = jdbcInsert.executeAndReturnKeyHolder(Map.of("val", "foo"));
// keyHolder.getKeys() will be empty!
However, completely bypassing the check from jdbc insert (pardon the messy code to get it done), will yield the correct result:
SimpleJdbcInsertjdbcInsert = newSimpleJdbcInsert(ds)
.withTableName("DEMO")
.usingColumns("val")
.usingGeneratedKeyColumns("id");
// manually compile to help bypassjdbcInsert.compile();
KeyHolderkeyHolder = newGeneratedKeyHolder();
// ugly and shameless copy pasting of pieces of AbstractJdbcInsert just to prove a pointjdbcInsert.getJdbcTemplate().update(
con -> {
PreparedStatementps = con.prepareStatement(jdbcInsert.getInsertString(), jdbcInsert.getGeneratedKeyNames());
int[] insertTypes = jdbcInsert.getInsertTypes();
StatementCreatorUtils.setParameterValue(ps, 1, insertTypes[0], "foo");
returnps;
},
keyHolder);
// keyHolder.getKeys() will contain the uuid!
Other database drivers, such as PostgreSQL, will work as expected when given an equivalent table (ie: setting a uuid primary key through a DEFAULT gen_random_uuid())
The text was updated successfully, but these errors were encountered:
The HSQLDB JDBC Driver (starting at 2.0) will return
true
when queried forgetGeneratedKeys
support atspring-framework/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java
Lines 96 to 98 in e7402bc
However, all versions of HSQLDB are explicitly blocked from specifying column names to retrieve as per
spring-framework/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java
Lines 52 to 53 in e7402bc
and instead fallback to using a generic
Statement.RETURN_GENERATED_KEYS
flagspring-framework/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java
Lines 540 to 557 in e7402bc
However, at least on current versions of HSQLDB, the support for column names is present, and even documented
source
Why does it matter? Because using
Statement.RETURN_GENERATED_KEYS
will only return columns that are either anIDENTITY
orGENERATED
column; but a primary key may be generated through a different means. For instance, take this simple table:Given the following
SimpleJdbcInsert
:However, completely bypassing the check from jdbc insert (pardon the messy code to get it done), will yield the correct result:
Other database drivers, such as PostgreSQL, will work as expected when given an equivalent table (ie: setting a uuid primary key through a
DEFAULT gen_random_uuid()
)The text was updated successfully, but these errors were encountered: