在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"}); 

希望能帮助别人。