Bug #26371 UpdatableResultSet.moveToInsertRow throws ClassCastException
Submitted: 14 Feb 2007 15:50 Modified: 13 Apr 2007 21:40
Reporter: Christopher Schultz Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:3.1.13 OS:Linux (Linux 2.6 kernel)
Assigned to: CPU Architecture:Any

[14 Feb 2007 15:50] Christopher Schultz
Description:
MySQL 5.0.26, Sun Java 1.5.0_10, and Connector/J 3.1.13

A fairly simple update method is failing with a ClassCastException:

java.lang.ClassCastException: [Ljava.lang.Object;
        at com.mysql.jdbc.UpdatableResultSet.moveToInsertRow(UpdatableResultSet.java:909)
        at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.moveToInsertRow(DelegatingResultSet.java:499)
        at (My Code)

It appears to be the same issue identified in bug 19451 (http://bugs.mysql.com/bug.php?id=19451), which was classified as "Not a Bug". I'm not sure I agree.

How to repeat:
Pseudocode for my update method is here (I'll work on a small, repeatable example to post).

BEGIN
SELECT pk, etc., ... FOR UPDATE

while(rs.next())
{
    // update existing rows
}

foreach(newRow in newRows)
{
   rs.moveToInsertRow();   // This line fails

   rs.update (...);
   rs.insertRow();
}

Just as with the original poster of bug 19451, my code fails when there is at least one row returned in the ResultSet.

My understanding of the JDBC spec is that ResultSet.moveToInsertRow ought to move the cursor to an appropriate location for inserting data. The fact that the resultset already has data in it shouldn't be relevant. The workaround of putting a ResultSet.beforeFirst() followed by a ResultSet.moveToInsertRow is a MySQL-specific hack that shouldn't be necessary.

Also note that the exception is ClassCastException. It occurs on this line of code:

                this.savedCurrentRow = (Object[]) this.thisRow;

Both 'savedCurrentRow' and 'thisRow' are declared to be of type Object[]. Why should this line of code throw an exception?

I recompiled the code for 3.1.13 myself (using 1.5.0 compiler) and added code to check the type of 'this.thisRow' which turns out to be "[Ljava.lang.Object", which should not result in a ClassCastException.

If the ResultSet is not in a sane state when ResultSet.moveToInsertRow is called, then some type of SQLException ought to be thrown, not a ClassCastException.

The same code running with Connector/J 5.0.4 does not cause this problem.
[11 Apr 2007 11:45] Tonci Grgin
Hi Christopher and thanks for your report. 
I too have my doubts regarding solution in Bug#19451 which is forwarded to c/J team for further clarification. 

Can you tell me in what way is this report different than Bug#26371 since I'm inclined to close it as duplicate and continue discussion in original report?
[11 Apr 2007 15:24] Tonci Grgin
Sorry, my mistake. It should be Bug#19451... Anyway, I've done some consults and this *is* a bug although the spec are not clear about "where" the insert row "lives", but you should be able to insert data even in result sets that aren't empty. There are some corner cases / gray areas though...

Setting this report to duplicate of Bug#19451 which is now "Verified".
[13 Apr 2007 21:40] Christopher Schultz
Tonci,

I believe that Bug#19451 and this one are the same thing. I argue that neither have been fixed.

There's no reason that these problems should cause a ClassCastException. It looks like in either case the ResultSet is beyond the last record in the result set. Calling ResultSet.moveToInsertRow should -- at most -- throw a SQLException if the cursor state is bad.

Throwing ClassCastException in production code is unacceptable. Looking at the source to Connector/J, I can't even figure out why the ClassCastException is being thrown. I have upgraded to a 5.x version of Connector/J and Java 1.5 since this report was filed and the problems have gone away. It is even possible that it was a JVM problem. <shrug>

I'm a little disappointed that no bug I've ever filed with MySQL has been resolved. :(
[14 Apr 2007 10:27] Tonci Grgin
Christopher, I appologize for the delay. Will ask c/J team for update on status.