问题描述
我正在使用CachedRowSet
.但是当我调用insertRow()
方法时,有一个SQLException
无法插入行.
I'm using CachedRowSet
. But when I call the insertRow()
method, there is a SQLException
failed to insert row.
这是我的代码:
static final String DATABASE_URL = "jdbc:mysql://localhost:3306/javapos";
static final String USERNAME = "root";
static final String PASSWORD = "sbc";
public static void main (String [] agr) throws SQLException
{
CachedRowSetImpl rs = new CachedRowSetImpl();
rs.setUrl(DATABASE_URL);
rs.setUsername(USERNAME);
rs.setPassword(PASSWORD);
rs.setCommand("select * from uom order by itemid");
rs.execute();
while(rs.next()){
System.out.println(rs.getString("itemid") + " - " + rs.getString("uom"));
}
rs.moveToInsertRow();
rs.updateString(2,"Sample code");
rs.insertRow();
rs.moveToCurrentRow();
rs.acceptChanges();
}
推荐答案
调用insertRow()
时,CachedRowSet
的参考实现会检查是否已填充了所有必需的列,否则会引发异常(源于 Grepcode CachedRowSet.insertRow()
,行号不完全匹配):
When you call insertRow()
, the Reference Implementation of CachedRowSet
performs a check if all required columns have been populated and otherwise it throws an exception (source from Grepcode CachedRowSet.insertRow()
, line numbers don't exactly match):
if (onInsertRow == false ||
insertRow.isCompleteRow(RowSetMD) == false) {
throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString());
}
检查在 InsertRow.isCompleteRow(RowSetMetaData)
:
public boolean isCompleteRow(RowSetMetaData RowSetMD) throws SQLException {
for (int i = 0; i < cols; i++) {
if (colsInserted.get(i) == false &&
RowSetMD.isNullable(i + 1) == ResultSetMetaData.columnNoNulls) {
return false;
}
}
return true;
}
换句话说,当插入一行时,您必须为所有不可为空的列(包括主键)提供一个值.似乎有两种方法可以解决此问题:
In other words, when inserting a row you must provide a value for all columns that are not nullable (this includes the primary key). There seem to be two ways to work around this:
- 设置(随机)值.这确实需要始终生成主键(即使提供了值).
- 使用
updateNull
将列明确设置为null
.使用setNull
不起作用:它会提供相同的错误,而使用setObject(idx, null)
会导致NullPointerException
- Setting a (random) value. This does require that your primary key is always generated (even if a value is provided).
- Explicitly setting the column to
null
usingupdateNull
. UsingsetNull
doesn't work: it provides the same error, and usingsetObject(idx, null)
results in aNullPointerException
在对这些更改使用代码时,在调用acceptChanges
时得到SQLException
,因为实现未禁用autoCommit
(它似乎是注释),但它确实显式调用commit
(在autoCommit
中无效).这似乎并不容易解决,除非可以在execute
上显式提供一个连接,或者创建自己的实现.
When using your code with these changes I get an SQLException
when calling acceptChanges
as the implementation doesn't disable autoCommit
(it seems to have been commented out), but it does explicitly call commit
(which is invalid when in autoCommit
). This doesn't seem to be easy to solve, except maybe explicitly providing a connection on execute
, or creating your own implementation.
我认为这类问题实际上表明了RowSet
实现的实际使用量(否则它们早就已经被淘汰了).
I think these kind of issues actually demonstrate how little the RowSet
implementations are actually used (otherwise they would already have been flushed out long ago).
但是请注意,如果这是您需要的实际代码,并且不需要CachedRowSet
的脱节特征,那么您可以简单地使用可更新的结果集.
Note however that if this were the actual code you needed and don't need the disconnected characteristics of the CachedRowSet
, then you could simply use an updatable result set.
这篇关于CachedRowSet无法插入行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!