Issue Details (XML | Word | Printable)

Key: NUCRDBMS-779
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Mark Rotteveel
Votes: 0
Watchers: 0
Operations

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

Without explicit commit, fetching multiple results fails with Firebird

Created: 23/Mar/14 04:33 PM   Updated: 17/Aug/14 11:40 AM   Resolved: 12/Aug/14 04:22 PM
Component/s: Connection
Affects Version/s: 3.2.12
Fix Version/s: 4.0.2

File Attachments: 1. Zip Archive datanucleus-app.zip (5 kB)
2. Text File ExceptionDetails.txt (7 kB)

Environment:
Jaybird 2.2.4
Firebird 2.5.2 Update 1

Datastore: Firebird


 Description  « Hide
With Jaybird 2.2.4, fetching multiple objects without an explicit transaction fails with an exception (see below and attached ExceptionDetails.txt). It looks like DataNucleus assumes that the ResultSet is HOLD_CURSORS_OVER_COMMIT which is not the default for Jaybird.

When executing the query, DataNucleus does:

1. execute query
2. check if there are results at org.datanucleus.store.rdbms.query.JDOQLQuery.performExecute(JDOQLQuery.java:735)
3. release the managed connection: at org.datanucleus.store.rdbms.query.JDOQLQuery.performExecute(JDOQLQuery.java:869)
4. When there is no explicit transaction: commit the transaction on the database connection: at org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl.release(ConnectionFactoryImpl.java:356)
5. Close the managed connection: at org.datanucleus.store.connection.AbstractManagedConnection.release(AbstractManagedConnection.java:77)
6. Fetch the remaining results before physically closing the connection: at org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl.close(ConnectionFactoryImpl.java:532)

The problem starts at step 4. The transaction commit closes the ResultSet, the subsequent fetch in step 6 triggers an exception as the result set is already closed (although due to an existing bug in Jaybird this is only detected when the fetch is actually sent to the server).

To me it looks like the ManagedConnectionListener.transactionPreClose() defined at org.datanucleus.store.rdbms.query.JDOQLQuery.performExecute(JDOQLQuery.java:740) should also be called for non-managed transactions if the resultset is not holdable over commits.

See http://stackoverflow.com/questions/22555377/firebird-sql-error-code-504-invalid-cursor-reference

mrt 23, 2014 3:44:06 PM org.datanucleus.store.rdbms.query.ForwardQueryResult closingConnection
INFO: Reading in results for query "SELECT FROM nl.lawinegevaar.jdo.Product WHERE price > value PARAMETERS int value" since the connection used is closing
Exception in thread "main" javax.jdo.JDOUserException: Exception thrown while loading remaining rows of query
at org.datanucleus.api.jdo.JDOAdapter.getUserExceptionForException(JDOAdapter.java:1139)
at org.datanucleus.store.rdbms.query.ForwardQueryResult.closingConnection(ForwardQueryResult.java:296)
at org.datanucleus.store.query.AbstractQueryResult.disconnect(AbstractQueryResult.java:107)
at org.datanucleus.store.rdbms.query.AbstractRDBMSQueryResult.disconnect(AbstractRDBMSQueryResult.java:236)
at org.datanucleus.store.rdbms.query.JDOQLQuery$2.managedConnectionPreClose(JDOQLQuery.java:753)
at org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl.close(ConnectionFactoryImpl.java:532)
at org.datanucleus.store.connection.AbstractManagedConnection.release(AbstractManagedConnection.java:77)
at org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl.release(ConnectionFactoryImpl.java:369)
at org.datanucleus.store.rdbms.query.JDOQLQuery.performExecute(JDOQLQuery.java:869)
at org.datanucleus.store.query.Query.executeQuery(Query.java:1786)
at org.datanucleus.store.query.Query.executeWithArray(Query.java:1672)
at org.datanucleus.api.jdo.JDOQuery.execute(JDOQuery.java:243)
at nl.lawinegevaar.jdo.JDOQuery.main(JDOQuery.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
NestedThrowablesStackTrace:
javax.jdo.JDODataStoreException: Failed to read the result set : GDS Exception. 335544332. invalid transaction handle (expecting explicit transaction start)
at org.datanucleus.api.jdo.JDOAdapter.getDataStoreExceptionForException(JDOAdapter.java:1150)
at org.datanucleus.store.rdbms.query.ForwardQueryResult.nextResultSetElement(ForwardQueryResult.java:233)
at org.datanucleus.store.rdbms.query.ForwardQueryResult$QueryResultIterator.next(ForwardQueryResult.java:403)
at
(full stacktrace attached)

Mark Rotteveel added a comment - 23/Mar/14 04:36 PM
Simple reproduction Maven project:
* Create an empty Firebird database
* Adjust the persistence xml

Run nl.lawinegevaar.nl.JDOPopulate to populate the database
Run nl.lawinegevaar.nl.JDOQuery to reproduce the problem

Mark Rotteveel made changes - 23/Mar/14 04:36 PM
Field Original Value New Value
Attachment ExceptionDetails.txt [ 12054 ]
Attachment datanucleus-app.zip [ 12055 ]
Andy Jefferson added a comment - 12/Aug/14 04:22 PM
GitHub master adds information to the DatastoreAdapter whether a database (JDBC) supports HOLD_CURSORS_OVER_COMMIT, and acts accordingly.

Andy Jefferson made changes - 12/Aug/14 04:22 PM
Status Open [ 1 ] Resolved [ 5 ]
Fix Version/s 4.0.2 [ 12235 ]
Resolution Fixed [ 1 ]
Andy Jefferson made changes - 17/Aug/14 11:40 AM
Status Resolved [ 5 ] Closed [ 6 ]