I've encountered some behaviors in OpenJPA which I did not expected, and wanted
to hear out from the community whether or not these are bugs in the product.
The first one is with how EntityManager.refresh() works when the data cache is
enabled. Page 105 in the JPA 2.0 Spec states "The retrieveMode property is
ignored for the refresh method, which always causes data to be retrieved from
the database, not the cache." However, it looks like refresh() is going to the
cache for state information instead of directly accessing the database for a
fresh set of data. I've confirmed this by setting up a JDBCListener, and no
observable SQL is captured by the refresh() operation.
---
The next issue I ran into is when I issue a refresh() requesting a lock, and
specifying a timeout hint with it. It looks like the timeout works, but
instead of getting a LockTimeoutException or a PessimisticLockException, I get
the following OptimisticLockException:
org.apache.openjpa.persistence.OptimisticLockException:Unable to obtain an
object lock on "null".
FailedObject: entities.EntityA-1 [java.lang.String]
at
org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4809)
at
org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4787)
at
org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:563)
at
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:136)
at
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:110)
at
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:62)
at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.syncVersion(JDBCStoreManager.java:329)
at
org.apache.openjpa.kernel.DelegatingStoreManager.syncVersion(DelegatingStoreManager.java:107)
at
org.apache.openjpa.kernel.ROPStoreManager.syncVersion(ROPStoreManager.java:67)
at
org.apache.openjpa.kernel.StateManagerImpl.syncVersion(StateManagerImpl.java:3245)
at
org.apache.openjpa.kernel.StateManagerImpl.beforeRefresh(StateManagerImpl.java:1301)
at
org.apache.openjpa.kernel.BrokerImpl.refreshInternal(BrokerImpl.java:3051)
at org.apache.openjpa.kernel.BrokerImpl.refresh(BrokerImpl.java:2922)
at
org.apache.openjpa.kernel.DelegatingBroker.refresh(DelegatingBroker.java:1126)
at
org.apache.openjpa.persistence.EntityManagerImpl.refresh(EntityManagerImpl.java:772)
...
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: Processing was
cancelled due to an interrupt.. SQLCODE=-952, SQLSTATE=57014, DRIVER=3.51.76
{prepstmnt 1166493063 SELECT t0.version FROM EntityA t0 WHERE t0.id = ? FOR
READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1]} [code=-952,
state=57014]
at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:257)
at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:241)
at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$700(LoggingConnectionDecorator.java:70)
at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeQuery(LoggingConnectionDecorator.java:1063)
at
org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:278)
at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeQuery(JDBCStoreManager.java:1731)
at
org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:268)
at
org.apache.openjpa.jdbc.sql.SelectImpl.executeQuery(SelectImpl.java:471)
at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:396)
at
com.ibm.ws.persistence.jdbc.sql.SelectImpl.execute(SelectImpl.java:77)
at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:354)
at
org.apache.openjpa.jdbc.meta.strats.ColumnVersionStrategy.checkVersion(ColumnVersionStrategy.java:292)
at org.apache.openjpa.jdbc.meta.Version.checkVersion(Version.java:353)
at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.syncVersion(JDBCStoreManager.java:327)
... 38 more
---
While on the locking topic, I found that the hint javax.persistence.lock.scope
= PessimisticLockScope.EXTENDED with refresh() seems to be ignored -- I seen no
SQL sent to the database which attempted to lock the related rows in the join
table, even after establishing the lock with the refresh() and walking through
the *:many relationship list to see if the SQL generated to access the join
table to fetch entities addressed by the relationship would become locked --
they did not.