在popup的行中插入自动生成的键3 / PostgreSQL 8.4.9
我想从行插入检索自动生成的id,但我得到一个NullPointerException
这里是代码:
long result = 0; final String SQL = "INSERT INTO compte (prenom, nom, datenaissance, numtelephone) " + " VALUES(?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); int row= this.jdbcTemplate.update(new PreparedStatementCreator(){ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { PreparedStatement ps =connection.prepareStatement(SQL); ps.setString(1, a.getSurname()); ps.setString(2, a.getName()); ps.setDate(3, a.getDob()); ps.setString(4, a.getPhone()); return ps; } },keyHolder); if (row > 0) result = keyHolder.getKey().longValue(); //line 72
这是PostgreSQL表:
CREATE TABLE compte ( idcompte serial NOT NULL, prenom character varying(25) NOT NULL, nom character varying(25) NOT NULL, datenaissance date NOT NULL, numtelephone character varying(15) NOT NULL, CONSTRAINT pk_compte PRIMARY KEY (idcompte ) );
PostgreSQL支持自动生成的密钥,但是我得到这个exception:
java.lang.NullPointerException at com.tante.db.JDBCUserAccountDAO.insertAccount(JDBCUserAccountDAO.java:72)
编辑:我试图得到自动生成的关键:
result = jdbcTemplate.queryForLong("select currval('compte_idcompte_seq')");
但是我得到一个PSQLException
:
the current value (currval) of the sequence compte_idcompte_seq is not defined in this session
,虽然我认为在插入compte_idcompte_seq.NEXTVAL
应该已经调用了compte_idcompte_seq.NEXTVAL
编辑:
当插入行时,自动增加值是正确创build的
任何想法 ?
KeyHolder holder = new GeneratedKeyHolder(); getJdbcTemplate().update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { PreparedStatement ps = connection.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS); ps.setString(1, person.getUsername()); ps.setString(2, person.getPassword()); ps.setString(3, person.getEmail()); ps.setLong(4, person.getRole().getId()); return ps; } }, holder); Long newPersonId = holder.getKey().longValue();
使用Spring JDBC从INSERT中获取密钥的最简单方法是使用SimpleJdbcInsert
类。 您可以在“Spring参考指南”的“ 使用SimpleJdbcInsert检索自动生成的密钥 ”一节中看到一个示例。
我使用的是Spring3.1 + PostgreSQL9.1,当我使用这个
KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { PreparedStatement ps = connection.prepareStatement(youSQL, Statement.RETURN_GENERATED_KEYS); ps.setString(1, post.name_author); ... return ps; } }, keyHolder); long id = keyHolder.getKey().longValue();
我得到这个例外:
org.springframework.dao.InvalidDataAccessApiUsageException: The getKey method should only be used when a single key is returned. The current key entry contains multiple keys: ...
所以我改为:
PreparedStatement ps = connection.prepareStatement(youSQL, new String[]{"id"});
“id”是
id serial not null primary key
问题解决了。 所以我认为使用
prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
这里不对 官方指南在这里 ,第13.2.8章:检索自动生成的密钥
似乎有一些Keyholder和PostgreSQL已知的问题。 看看这个链接的解决方法Spring JDBC – 最后插入的ID
也请直接检查数据库表,看是否正确插入logging(即与PK)。 这将有助于缩小问题的范围。
看看这篇文章,特别是使用INSERT … RETURNING语法的公认的答案:
如何从最后插入的行中获取值?
这是在PostgreSQL中获得这个值的最好方法,因为你只做一个networking往返,并且在服务器上完成一个单一的primefaces操作。
使用带有Sequence.nextval的NamedParameterJdbcTemplate的解决scheme:
MapSqlParameterSource parameters = new MapSqlParameterSource(); parameters.addValue("prenom", prenom); parameters.addValue("nom", nom); parameters.addValue("datenaissance", datenaissance); parameters.addValue("numtelephone", numtelephone); final String SQL = "INSERT INTO compte (idcompte, prenom, nom, datenaissance, numtelephone) " + " VALUES(compte_idcompte_seq.NEXTVAL, :prenom, :nom, :datenaissance, :numtelephone)"; KeyHolder keyHolder = new GeneratedKeyHolder(); NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(txManager.getDataSource()); int nb = namedJdbcTemplate.update(SQL, parameters, keyHolder, new String[]{"idcompte"}); Long generatedId = keyHolder.getKey().longValue();
我有同样的问题,事实certificate,我的表ID不是自动递增。
我面临类似的问题。 我不知道为什么我正好面对这个问题,但好东西是我需要通过使用下面的代码来解决这个问题:
final KeyHolder holder = new GeneratedKeyHolder(); int status = myTemplate.update(yourInsertSQL, namedParameters, holder, new String[]{"PrimaryKeyColumnName"});
希望能帮助别人。