Springs SimpleJdbcInsert doesn't produce auto-generated keys as expected
I'm using springs SimpleJdbcInsert to execute an JDBC insert and return 2 auto-generated keys.
The command I use is:
KeyHolder keys = insert.withTableName("TRANSACTION").usingGeneratedKeyColumns("TRANSACTIONID", "ROWID").executeAndReturnKeyHolder(params);
But keys
only contains one key named SCOPE_IDENTITY()
The logs seem to indicate that things are going well, except that the auto-generated keys for TRANSACTIONID AND ROWID don't get populated, here are some relevant logs
DEBUG o.s.jdbc.core.simple.SimpleJdbcInsert - JdbcInsert not compiled before execution - invoking compile
DEBUG o.s.jdbc.core.metadata.TableMetaDataProviderFactory - Using GenericTableMetaDataProvider
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - GetGeneratedKeys is supported
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - GeneratedKeysColumnNameArray is supported for H2
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieving metadata for PRIMARY.DB/PUBLIC/TRANSACTION
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: TRANSACTIONID 4 false
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: CREDITS 3 true
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: TXNTYPE -6 true
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: CARDTXNID 12 true
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: DATE 93 true
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: ROWID 4 false
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: CARDINFOID 4 true
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: PAYMENTMETHOD -6 true
DEBUG o.s.jdbc.core.metadata.TableMetaDataProvider - Retrieved metadata: USERID 4 true
DEBUG o.s.jdbc.core.simple.SimpleJdbcInsert - Compiled JdbcInsert. Insert string is [INSERT INTO TRANSACTION (CREDITS, TXNTYPE, CARDTXNID, DATE, CARDINFOID, PAYMENTMETHOD, USERID) VALUES(?, ?, ?, ?, ?, ?, ?)]
DEBUG o.s.jdbc.core.simple.SimpleJdbcInsert - JdbcInsert for table [TRANSACTION] compiled
DEBUG o.s.jdbc.core.simple.SimpleJdbcInsert - The following parameters are used for call INSERT INTO TRANSACTION (CREDITS, TXNTYPE, CARDTXNID, DATE, CARDINFOID, PAYMENTMETHOD, USERID) VALUES(?, ?, ?, ?, ?, ?, ?) with: [10, 2, 64H80073VY322412Y, 2011-03-30 14:05:12.526, null, 2, null]
DEBUG o.s.jdbc.core.JdbcTemplate - Executing SQL update and returning generated keys
DEBUG o.s.开发者_如何学Pythonjdbc.core.JdbcTemplate - Executing prepared SQL statement
DEBUG o.s.jdbc.core.simple.SimpleJdbcInsert - Using generated keys support with array of column names.
DEBUG o.s.jdbc.core.JdbcTemplate - SQL update affected 1 rows and returned 1 keys
This was an issue with the H2 database I am using. It does not support returning more than one auto generated key.
Try this.
This is a complete save method which saves companyCarrier object with two properties set. These properties have datatypes of Integer and String.
Generated key is then set on the id property of the companyCarrier object.
Object[] args = { companyCarrier.getCompanyId(),
companyCarrier.getCarrierId() };
Class<?>[] parameterTypes = { CompanyCarrier.class };
int[] types = { Types.INTEGER, Types.VARCHAR };
SqlUpdate su = new SqlUpdate();
su.setJdbcTemplate(getJdbcTemplate());
su.setSql(getSqlQuery(getClass(), "save", parameterTypes));
setSqlTypes(su, types);
su.setReturnGeneratedKeys(true);
su.compile();
KeyHolder keyHolder = new GeneratedKeyHolder();
su.update(args, keyHolder);
int id = keyHolder.getKey().intValue();
if (su.isReturnGeneratedKeys()) {
companyCarrier.setId(id);
} else {
throw new RuntimeException("No key generated for insert statement");
}
精彩评论