keyHolder.getKey() return null
Asked Answered
K

3

22

Why code from "Spring in action 5" don't work (keyHolder.getKey() return null, but entity is saved in DB)?

private long savePizzaInfo(Pizza pizza) {
    pizza.setCreatedAt(new Date());
    PreparedStatementCreator psc =
            new PreparedStatementCreatorFactory(
                    "insert into PIZZA (name, createdAt) values (?, ?)",
                    Types.VARCHAR, Types.TIMESTAMP
            ).newPreparedStatementCreator(
                    Arrays.asList(
                            pizza.getName(),
                            new Timestamp(pizza.getCreatedAt().getTime())));
    KeyHolder keyHolder = new GeneratedKeyHolder();
    template.update(psc, keyHolder);
    return keyHolder.getKey().longValue();
}

My DB Table:

CREATE TABLE PIZZA
(
ID bigint DEFAULT (NEXT VALUE FOR 
PUBLIC.SYSTEM_SEQUENCE_12CA966F_4FFD_469C_BA69_80BB93916EF3) AUTO_INCREMENT 
PRIMARY KEY NOT NULL,
NAME varchar(50) NOT NULL,
CREATEDAT timestamp NOT NULL
);
CREATE UNIQUE INDEX PRIMARY_KEY_4 ON PIZZA (ID);
Knecht answered 6/12, 2018 at 16:25 Comment(4)
What do you mean by "PreparedStatementCreatorFactory return null"?Scandal
Sorry mistake, KeyHolder return null.Knecht
You mean keyHolder.getKey() returns null?Scandal
Yes, keyHolder.getKey() returns null.Knecht
S
34

You have to instruct PreparedStatementCreatorFactory instance to return the generated keys:

PreparedStatementCreatorFactory preparedStatementCreatorFactory = new PreparedStatementCreatorFactory(
         "insert into PIZZA (name, createdAt) values (?, ?)",
         Types.VARCHAR, Types.TIMESTAMP
 );

// By default, returnGeneratedKeys = false so change it to true
preparedStatementCreatorFactory.setReturnGeneratedKeys(true);

 PreparedStatementCreator psc =
         preparedStatementCreatorFactory.newPreparedStatementCreator(
                    Arrays.asList(
                            pizza.getName(),
                            new Timestamp(pizza.getCreatedAt().getTime())));
Scandal answered 6/12, 2018 at 17:46 Comment(0)
W
8

You need to specify your prepared statement notice the Statement.RETURN_GENERATED_KEYS in the code bellow you need something like this

final PreparedStatementCreator psc = new PreparedStatementCreator() {
      @Override
      public PreparedStatement createPreparedStatement(final Connection connection) throws SQLException {
        final PreparedStatement ps = connection.prepareStatement("INSERT INTO `names` (`name`) VALUES (?)",
            Statement.RETURN_GENERATED_KEYS);
        ps.setString(1, name);
        return ps;
      }
    };
Woodchuck answered 6/12, 2018 at 16:55 Comment(0)
P
0

Why not use SimpleJdbcInsert instead?

dbcInsert = new SimpleJdbcInsert(jdbcTemplate);
        jdbcInsert.withTableName("TABLE_NAME").usingGeneratedKeyColumns(
                "Primary_key");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("Column_NAME1", bean.getval1());
        parameters.put("Column_NAME2", bean.getval2());
        // execute insert
        Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(
                parameters));
           // convert Number to Int using ((Number) key).intValue()
            return ((Number) key).intValue();
Pinder answered 6/12, 2018 at 17:0 Comment(1)
This is used later in the book.Snuffer

© 2022 - 2024 — McMap. All rights reserved.