You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by J Grassel <fy...@gmail.com> on 2010/05/05 17:05:28 UTC

JPA 2.0 EntityManager.refresh() Behavior

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. 


Re: JPA 2.0 EntityManager.refresh() Behavior

Posted by Rick Curtis <cu...@gmail.com>.
Sounds like you found a few bugs. I'd suggest opening up a JIRA for each and
post a testcase.

On Wed, May 5, 2010 at 10:05 AM, J Grassel <fy...@gmail.com> wrote:

> 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.
>
>


-- 
Thanks,
Rick