Jer*_*ith 44 java postgresql spring jdbc auto-generate
我想从行插入中检索自动生成的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
Run Code Online (Sandbox Code Playgroud)
这是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 )
);
Run Code Online (Sandbox Code Playgroud)
PostgreSQL支持自动生成的密钥,但是我得到了这个异常:
java.lang.NullPointerException
at com.tante.db.JDBCUserAccountDAO.insertAccount(JDBCUserAccountDAO.java:72)
Run Code Online (Sandbox Code Playgroud)
编辑:我试过这个来获取自动生成的密钥:
result = jdbcTemplate.queryForLong("select currval('compte_idcompte_seq')");
Run Code Online (Sandbox Code Playgroud)
但我得到一个PSQLException
:
the current value (currval) of the sequence compte_idcompte_seq is not defined in this session
虽然我认为compte_idcompte_seq.NEXTVAL
在插入行时应该调用它
编辑:
插入行时,会正确创建自动增量值
任何的想法 ?
小智 59
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();
Run Code Online (Sandbox Code Playgroud)
请注意,在较新版本的Postgres中,您需要使用
connection.prepareStatement(sql.toString(),
new String[] { "idcompte" /* name of your id column */ })
Run Code Online (Sandbox Code Playgroud)
代替
connection.prepareStatement(sql.toString(),
Statement.RETURN_GENERATED_KEYS);
Run Code Online (Sandbox Code Playgroud)
Pau*_*aul 22
使用Spring JDBC从INSERT获取密钥的最简单方法是使用SimpleJdbcInsert
该类.您可以在"Spring参考指南"的" 使用SimpleJdbcInsert检索自动生成的密钥 "一节中看到一个示例.
小智 14
我正在使用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();
Run Code Online (Sandbox Code Playgroud)
我有这个例外:
org.springframework.dao.InvalidDataAccessApiUsageException:
The getKey method should only be used when a single key is returned.
The current key entry contains multiple keys: ...
Run Code Online (Sandbox Code Playgroud)
所以我改为:
PreparedStatement ps =
connection.prepareStatement(youSQL, new String[]{"id"});
Run Code Online (Sandbox Code Playgroud)
其中"id"是
id serial not null primary key
Run Code Online (Sandbox Code Playgroud)
问题解决了.所以我认为使用
prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
Run Code Online (Sandbox Code Playgroud)
不在这里 官方指南在这里,第13.2.8节:检索自动生成的密钥
使用NamedParameterJdbcTemplate和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();
Run Code Online (Sandbox Code Playgroud)
我喜欢这个解决方案因为NamedParameterJdbcTemplate,因为参数是通过名称传递的,代码更易读,更不容易出错,特别是在有大查询时.
归档时间: |
|
查看次数: |
77223 次 |
最近记录: |