yet postgres pgconnection org not method implemented example createclob conectar con java spring postgresql jdbc auto-generate

java - pgconnection - Obtener la clave generada automáticamente desde la inserción de fila en el resorte 3/PostgreSQL 8.4.9



spring boot 2 postgresql (8)

Me gustaría recuperar el ID generado automáticamente desde una inserción de fila, pero obtengo una NullPointerException

Aquí está el código:

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

Y esta es la tabla de 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 admite claves generadas automáticamente, pero obtengo esta excepción:

java.lang.NullPointerException at com.tante.db.JDBCUserAccountDAO.insertAccount(JDBCUserAccountDAO.java:72)

EDITAR: Intenté esto para obtener la clave generada automáticamente:

result = jdbcTemplate.queryForLong("select currval(''compte_idcompte_seq'')");

pero obtengo una PSQLException :

the current value (currval) of the sequence compte_idcompte_seq is not defined in this session , aunque pensé que se debería haber llamado compte_idcompte_seq.NEXTVAL al insertar la fila

EDITAR:

El valor de autoincremento se crea correctamente cuando se inserta una fila

Alguna idea ?


Eche un vistazo a esta publicación, especialmente la respuesta aceptada de usar la sintaxis INSERTAR ... DEVOLVER:

¿Cómo obtener un valor de la última fila insertada?

Esta es la mejor manera de obtener este valor en PostgreSQL, ya que solo realiza una ida y vuelta de red y se realiza como una única operación atómica en el servidor.


Enfrenté el problema similar. No sé por qué exactamente enfrenté este problema, pero lo bueno es que tengo que resolver esto usando el siguiente código:

final KeyHolder holder = new GeneratedKeyHolder(); int status = myTemplate.update(yourInsertSQL, namedParameters, holder, new String[]{"PrimaryKeyColumnName"});

Espero que ayude a alguien.


Estoy usando Spring3.1 + PostgreSQL9.1, y cuando uso esto

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();

Tengo esta excepción:

org.springframework.dao.InvalidDataAccessApiUsageException: The getKey method should only be used when a single key is returned. The current key entry contains multiple keys: ...

Entonces cambié a:

PreparedStatement ps = connection.prepareStatement(youSQL, new String[]{"id"});

donde "id" es

id serial not null primary key

Y el problema está resuelto. Así que supuse que usar

prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

no está aquí mismo La guía oficial está here , Capítulo 13.2.8: Recuperar claves autogeneradas



Parece haber algunos problemas conocidos con Keyholder y PostgreSQL. Eche un vistazo a la solución en este enlace Spring JDBC - Último ID insertado

También verifique la tabla de la base de datos directamente para ver si el registro se insertó correctamente (es decir, con PK). Esto ayudará a reducir el problema.


Tuve el mismo problema y resultó que mi ID de tabla no se incrementaba automáticamente.


Una solución que usa NamedParameterJdbcTemplate con Sequence.nextval:

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();

Me gusta esta solución debido a NamedParameterJdbcTemplate porque los parámetros se pasan por nombre y el código es más legible y menos propenso a errores, especialmente cuando hay grandes consultas.


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();

Tenga en cuenta que en las versiones más nuevas de Postgres debe usar

connection.prepareStatement(sql.toString(), new String[] { "idcompte" /* name of your id column */ })

en lugar de

connection.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);