CachedRowSet的失败中插入一行(CachedRowSet failed to insert

2019-10-20 23:20发布

我使用CachedRowSet 。 但是,当我打电话insertRow()方法,有一个SQLException未能插入一行。

这里是我的代码:

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

Answer 1:

当你调用insertRow()参考实现CachedRowSet执行是否已填充所有需要的列的检查,否则它抛出(从源异常Grepcode CachedRowSet.insertRow()行数不完全匹配):

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;
}

换句话说,插入一行时,你都必须为不可为空的所有列(包括主键)的值。 似乎有解决此两种方法:

  • 设置一个(随机)值。 这确实需要你的主键始终会生成(即使提供的值)。
  • 明确将列设置为null使用updateNull 。 使用setNull不起作用:它提供了相同的错误,并且使用setObject(idx, null)导致NullPointerException

当使用这些变化,我得到一个你的代码SQLException打电话时acceptChanges作为实现不会禁用autoCommit (它似乎已被注释掉 ),但它并明确调用commit (这是无效时autoCommit )。 这似乎并不容易解决,也许除了明确规定上的连接execute ,或者创建自己的实现。

我觉得这些种问题,实际上证明了多么小RowSet实现实际使用(否则他们就已经刷新了很久以前)。

然而,需要注意的是,如果这是你需要的和不需要的断开特性的实际代码CachedRowSet ,那么你可以简单地使用可更新的结果集。



文章来源: CachedRowSet failed to insert row