Issue Details (XML | Word | Printable)

Key: NUCRDBMS-242
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: No Testcase No Testcase
Assignee: Andy Jefferson
Reporter: Yang ZHONG
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Store RDBMS

May be DB/driver bug, however AbstractLargeBinaryRDBMSMapping could be more robust

Created: 12/Aug/09 01:25 AM   Updated: 26/Apr/10 03:39 PM   Resolved: 13/Apr/10 02:32 PM
Component/s: None
Affects Version/s: 1.1.3
Fix Version/s: 2.1.0.m2

Environment: Linux, JDK 5, DB2 9.1.0.2

Datastore: IBM DB2
Severity: Production


 Description  « Hide
Knowing the Test Case requirement, ones have been failed to reproduce the below problem. Reproducible in local environment which can't be uploaded...

The following problem looks like DB/driver bug, however AbstractLargeBinaryRDBMSMapping could be more robust and move on working around the DB/driver bug.

org.datanucleus.exceptions.NucleusDataStoreException: Insert of object "...Jdo@438c438c" using statement "INSERT INTO schema.table (field1,BLOB2,...,PrimaryKey,version,discriminator) VALUES (?,?,...,?,?,?)" failed : DB2 SQL Error: SQLCODE=-301, SQLSTATE=07006, SQLERRMC=2, DRIVER=3.53.95
  at org.datanucleus.store.rdbms.request.InsertRequest.execute(InsertRequest.java:500)
  at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertTable(RDBMSPersistenceHandler.java:187)
  at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertObject(RDBMSPersistenceHandler.java:166)
  at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3097)
  at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4425)
  at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2841)
  at org.datanucleus.ObjectManagerImpl.markDirty(ObjectManagerImpl.java:2651)
  at org.datanucleus.state.JDOStateManagerImpl.postWriteField(JDOStateManagerImpl.java:4271)
  at org.datanucleus.state.JDOStateManagerImpl.setObjectField(JDOStateManagerImpl.java:2317)

It means "The value of parameter number 2 cannot be used because of its data type". "The value" was null and "its data type" was BLOB. I've debugged InsertRequest which sets the BLOB to null and no one sets the BLOB to anything else (I suspected StateManager#provideFields sets the BLOB to other field value). In order to debug InsertRequest easily, I modified InsertRequest.java to execute the Prepared Statement again if SQLException#getErrorCode==-301. Interestingly, the following execution throws SQLException w/ -803 which means last insertion (-301) actually succeeded!

Unfortunately, simple Test Cases couldn't reproduce that.

During debugging, I've noticed DataNucleus uses PreparedStatement#setNull for other data types, while AbstractLargeBinaryRDBMSMapping#setObject uses PreparedStatement#setBytes(,null).

Although the above problem may come from DB/driver, can we improve AbstractLargeBinaryRDBMSMapping/BlobRDBMSMapping to use PreparedStatement#setNull as well please?

Thanks!

Sort Order: Ascending order - Click to sort in descending order
Andy Jefferson added a comment - 12/Aug/09 07:31 AM - edited
Testcase requirement is a requirement. How can anybody think about your issue without seeing it ?
If you want improvements in some particular area you know the ways of going about it; contributions (aka patches), donations, support/consulting.

Yang ZHONG added a comment - 15/Oct/09 04:38 PM
Same fix is also applicable to all 1.1.4, 1.1.5 & 1.1.6.

Andy Jefferson added a comment - 13/Apr/10 02:32 PM
AbstractLargeBinaryRDBMSMapping.setObject now uses setNull when the value is null and the column is not defaultable. No idea if this fixes or otherwise of this problem but since there is no testcase and no adequate definition that is left as an exercise.