[SPRING] 스프링 3에서 자동 삽입 된 키 얻기 / PostgreSQL 8.4.9
SPRING스프링 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은 자동 생성 키를 지원하지만이 예외가 발생합니다 :
java.lang.NullPointerException
at com.tante.db.JDBCUserAccountDAO.insertAccount(JDBCUserAccountDAO.java:72)
편집하다 : 자동 생성 된 키를 얻으려면이 시도했다 :
result = jdbcTemplate.queryForLong("select currval('compte_idcompte_seq')");
하지만 PSQLException 얻을 :
compte_idcompte_seq.NEXTVAL이라고 생각했지만이 세션에서는 compte_idcompte_seq 시퀀스의 현재 값 (currval)이 정의되어 있지 않습니다. 행을 삽입 할 때 호출해야합니다.
편집하다 :
행이 삽입되면 자동 증가 값이 올바르게 생성됩니다.
어떤 생각?
해결법
-
==============================
1.
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();
최신 버전의 Postgres에서는 다음을 사용해야합니다.
connection.prepareStatement(sql.toString(), new String[] { "idcompte" /* name of your id column */ })
대신에
connection.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);
-
==============================
2.Spring JDBC로 INSERT에서 키를 얻는 가장 쉬운 방법은 SimpleJdbcInsert 클래스를 사용하는 것이다. 예제는 Spring Reference Guide의 SimpleJdbcInsert를 사용하여 자동 생성 키 검색 섹션에서 볼 수있다.
Spring JDBC로 INSERT에서 키를 얻는 가장 쉬운 방법은 SimpleJdbcInsert 클래스를 사용하는 것이다. 예제는 Spring Reference Guide의 SimpleJdbcInsert를 사용하여 자동 생성 키 검색 섹션에서 볼 수있다.
-
==============================
3.나는 Spring 3.1 + PostgreSQL 9.1을 사용하고 있는데 이것을 사용할 때
나는 Spring 3.1 + PostgreSQL 9.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 절. 자동 생성 키 검색
-
==============================
4.Sequence.nextval과 함께 NamedParameterJdbcTemplate을 사용하는 솔루션 :
Sequence.nextval과 함께 NamedParameterJdbcTemplate을 사용하는 솔루션 :
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();
NamedParameterJdbcTemplate을 사용하면 매개 변수가 이름으로 전달되고 코드가 읽기 쉽고 오류가 발생하지 않기 때문에 특히 큰 쿼리가있을 때이 솔루션이 마음에 들다.
-
==============================
5.Keyholder 및 PostgreSQL에는 몇 가지 알려진 문제가있는 것으로 보입니다. 이 링크에서 해결 방법을 살펴 보자. Spring JDBC - 마지막 삽입 ID
Keyholder 및 PostgreSQL에는 몇 가지 알려진 문제가있는 것으로 보입니다. 이 링크에서 해결 방법을 살펴 보자. Spring JDBC - 마지막 삽입 ID
또한 데이터베이스 테이블을 직접 점검하여 레코드가 올바르게 삽입되었는지 (즉 PK로) 확인하십시오. 이렇게하면 문제의 범위를 좁히는 데 도움이됩니다.
-
==============================
6.이 게시물, 특히 INSERT ...를 사용하여 받아 들여지는 답변을 살펴보십시오. RETURNING syntax :
이 게시물, 특히 INSERT ...를 사용하여 받아 들여지는 답변을 살펴보십시오. RETURNING syntax :
마지막으로 삽입 된 행에서 값을 가져 오는 방법은 무엇입니까?
이것은 PostgreSQL에서이 값을 얻는 가장 좋은 방법은 하나의 네트워크 왕복을 만들고 서버에서 단일 원자 연산으로 수행하기 때문입니다.
-
==============================
7.나는 동일한 문제가 있었는데 내 테이블 ID가 자동으로 증가하지 않는 것으로 밝혀졌습니다.
나는 동일한 문제가 있었는데 내 테이블 ID가 자동으로 증가하지 않는 것으로 밝혀졌습니다.
-
==============================
8.나는 비슷한 문제에 직면했다. 왜 내가이 문제에 직면했는지 모르겠지만 좋은 점은 아래 코드를 사용하여이 문제를 해결해야한다는 것입니다.
나는 비슷한 문제에 직면했다. 왜 내가이 문제에 직면했는지 모르겠지만 좋은 점은 아래 코드를 사용하여이 문제를 해결해야한다는 것입니다.
final KeyHolder holder = new GeneratedKeyHolder(); int status = myTemplate.update(yourInsertSQL, namedParameters, holder, new String[]{"PrimaryKeyColumnName"});
희망은 누군가를 돕습니다.
-
==============================
9.
setGeneratedKeysColumnNames(new String[]{"column_name"});
자동 생성 된 열의 이름을 설정하는 것을 잊지 마십시오.
from https://stackoverflow.com/questions/10597477/getting-auto-generated-key-from-row-insertion-in-spring-3-postgresql-8-4-9 by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 데이터 REST로 중첩 된 엔티티를 POST하는 방법 (0) | 2019.01.10 |
---|---|
[SPRING] 어노테이션을 사용하여 RestTemplate을 자동 작성하는 방법 (0) | 2019.01.10 |
[SPRING] Sun JSTL taglib 선언이 "태그 라이브러리 설명자를 찾을 수 없습니다"와 함께 실패합니다 [duplicate] (0) | 2019.01.10 |
[SPRING] <mvc : default-servlet-handler />의 필요성과 사용법은 무엇입니까? (0) | 2019.01.10 |
[SPRING] Spring Boot로 어떻게 다른 데이터베이스 설정을 제공 할 수 있습니까? (0) | 2019.01.10 |