Using Spring's KeyHolder with programmatically-generated primary keys
Just solved a similar issue - with Oracle you need to use another method (from NamedParameterJdbcOperations
) -
int update(String sql,
SqlParameterSource paramSource,
KeyHolder generatedKeyHolder,
String[] keyColumnNames)
throws DataAccessException
with keyColumnNames containing auto-generated columns, in my case just ["Id"]. Otherwise all you get is ROWID. See Spring doc for details.
You have to execute the JdbcTemplate.update(PreparedStatementCreator p, KeyHolder k)
.
The key returned from the database will be injected into the KeyHolder
parameter object.
An example:
final String INSERT_ORDER_STATEMENT
= "insert into order (product_id, quantity) values(?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(
Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(
INSERT_ORDER_STATEMENT, new String[] { "id" });
ps.setInt(1, order.getProductId());
ps.setInt(2, order.getQuantity());
return ps;
}
}, keyHolder);
More information can be found here in the reference documentation.
No elaborate on @konstantin answer: Here is a fully working example: Assuming Database is Oracle and column name which store generated Id is "GENERATED_ID" ( Can be any name). NOTE: I used NamedParameterJdbcTemplate.update(....) In this example NOT JdbcTemplate class of Spring.
public Integer insertRecordReturnGeneratedId(final MyObject obj)
{
final String INSERT_QUERY = "INSERT INTO MY_TABLE VALUES(GENERATED_ID_SEQ.NEXTVAL, :param1, :param2)";
try
{
MapSqlParameterSource parameters = new MapSqlParameterSource().addValue( "param1", obj.getField1() ).addValue( "param2", obj.getField1() ) ;
final KeyHolder holder = new GeneratedKeyHolder();
this.namedParameterJdbcTemplate.update( INSERT_QUERY, parameters, holder, new String[] {"GENERATED_ID" } );
Number generatedId = holder.getKey();
// Note: USING holder.getKey("GENERATED_ID") IS ok TOO.
return generatedId.intValue();
}
catch( DataAccessException dataAccessException )
{
}
}