JDK-6458333 : DataSet.insert() may fail when multiple threads attempt to insert. No exception is thrown.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.sql
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2006-08-09
  • Updated: 2011-02-16
  • Resolved: 2006-08-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
6 b98Fixed
Related Reports
Relates :  
Zero or more threads in the attached test case may fail to insert with the message:

java.sql.SQLException: Exception encountered: java.sql.SQLException: The last argument must be either a Connection or a DataSource
        at com.sun.sql.QueryObjectGeneratorImpl.getQueryImpl(QueryObjectGeneratorImpl.java:769)
        at com.sun.sql.QueryObjectGeneratorImpl.access$100(QueryObjectGeneratorImpl.java:24)
        at com.sun.sql.QueryObjectGeneratorImpl$2.run(QueryObjectGeneratorImpl.java:221)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.sql.QueryObjectGeneratorImpl.invoke(QueryObjectGeneratorImpl.java:216)
        at $Proxy0.getAddresses(Unknown Source)
        at ConcurrentQueryObjectTest.insertAddress(ConcurrentQueryObjectTest.java:126)
        at ConcurrentQueryObjectTest$ClientThread.run(ConcurrentQueryObjectTest.java:164)
        at java.lang.Thread.run(Thread.java:619)
Inserting address in thread ThreadSafeID-9
Failed to insert address in thread ThreadSafeID-9
        at ConcurrentQueryObjectTest.insertAddress(ConcurrentQueryObjectTest.java:129)
        at ConcurrentQueryObjectTest$ClientThread.run(ConcurrentQueryObjectTest.java:164)
        at java.lang.Thread.run(Thread.java:619)import java.sql.BaseQuery;

The stack trace is displayed but no exception is thrown.  (The NPE occurs after the initial problem.)  The error message displayed is not informative for the user.

SUGGESTED FIX Fix for bug 6458333/6460067. Incoporated Craig and Binod suggestions. Made connection and datasource non-static. Also created a new class QueryObject and moved all query related invocations to QueryObject. QueryObjectGeneratorImpl in now a simple implementation of QueryObjectGenerator interface. It now creates instance of QueryObject and passes it to application which calls createQueryObject(). checkin logs : RCS file: /m/jws/jdbc4.0/src/com/sun/sql/QueryObject.java,v done Checking in QueryObject.java; /m/jws/jdbc4.0/src/com/sun/sql/QueryObject.java,v <-- QueryObject.java initial revision: 1.1 done Checking in QueryObjectGeneratorImpl.java; /m/jws/jdbc4.0/src/com/sun/sql/QueryObjectGeneratorImpl.java,v <-- QueryObjectGeneratorImpl.java new revision: 1.61; previous revision: 1.60 done

SUGGESTED FIX I looked at the code as well. Besides all that Craig wrote, it will be good, if we can split QueryObjectGeneratorImpl into a better design, at a minimum encapsulating the proxy query object to another class.

SUGGESTED FIX 1. Remove the ThreadLocal code from the QueryObjectGeneratorImpl class. There are no thread-local requirements for the class. 2. Remove the "static" declaration from DataSource dSource and Connection conn. These should be fields of the instance used to create and manage a QueryObject instance. 3. Create constructors for QueryObjectGeneratorImpl that take a DataSource and a Connection, respectively. 4. Call these constructors from the factory methods createQueryObject(ifc, DataSource) and createQueryObject(ifc, Connection).

EVALUATION This is not a JDBC EOD bug. The eod code is thread safe. There are test case and derby issues with this. A) Test Case : 1. The createQueryObject() of Connection is being used in the test case. This will be driver specific. Please use QueryObjectFactory.createQueryObject() instead to test EDOD code. B) Derby issues : 1. Before runThreads() there is an open connection. In insertAddress() another connection is being created that will cause exceptions. This is a derby problem. 2. Updatable ResultSet has been implemented in derby after 10.2 version. Hence, after the other corrections, tests will fail because ResultSet is CONCUR_READ_ONLY. Please test the test case after resolving test case and derby issues. I will then close this as not a bug. I tested the test case without any changes, with Oracle DB. It is passing.

EVALUATION Being worked on