【问题标题】:CachedRowSet failed to insert rowCachedRowSet 插入行失败
【发布时间】:2014-09-13 03:20:55
【问题描述】:

我正在使用CachedRowSet。但是当我调用insertRow()方法时,出现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();
}

【问题讨论】:

  • 请包含错误堆栈跟踪。
  • 线程“主”java.sql.SQLException 中的异常:在 purchase.NewClass.main(NewClass. java:39) Java 结果:1
  • 应该有更多的信息。
  • 除了 System.out.prinln,这是唯一出现的错误堆栈跟踪
  • 请在问题本身中包含 full 堆栈跟踪。

标签: java jdbc cachedrowset


【解决方案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;
}

换句话说,在插入一行时,您必须为所有不可为空的列(包括主键)提供一个值。似乎有两种方法可以解决这个问题:

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

当使用您的代码进行这些更改时,我在调用acceptChanges 时得到一个SQLException,因为实现不会禁用autoCommit(它似乎是commented out),但它确实显式调用commit (在autoCommit 中无效)。这似乎并不容易解决,除非在execute 上明确提供连接,或者创建您自己的实现。

我认为这类问题实际上表明了 RowSet 实现的实际使用量有多么少(否则它们早就被淘汰了)。

但是请注意,如果这是您需要的实际代码并且不需要 CachedRowSet 的断开连接特性,那么您可以简单地使用可更新的结果集。

【讨论】:

  • 解决方案是在非自动提交模式下提供到acceptConnection() 的连接,或者配置它的连接或它的数据源,如果这是你正在使用的。我同意缺乏使用,我发现了其他一些奇怪和错误。似乎根本没有人使用它。真可惜,里面有一些好主意。我将打开一个关于它的文档错误报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
  • 2011-10-24
  • 2012-08-13
  • 2019-10-12
  • 2014-11-23
相关资源
最近更新 更多