[
https://issues.apache.org/jira/browse/OPENJPA-462?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12549180
]
Pinaki Poddar commented on OPENJPA-462:
---------------------------------------
An optimistic violation often manifests as a SQLException during implicit or
explicit flush/commit operation.
As this SQL exception bubbles up the stack of OpenJPA layers, the exception
gets translated with the original exception being nested within.
The OpenJPA facade translates an exception to
javax.persistence.OptimisticLockException for the user application *if* the
lower layer
(i.e. spec-agnostic OpenJPA kernel) raises or translates original SQLException
to a org.apache.openjpa.util.OptimisticException.
If the context is not sufficient to translate the exception to
org.apache.openjpa.util.OptimisticException, it gets translated to
org.apache.openjpa.util.StoreException which is the generic type from all
exceptions raised by the underlying datastore (which is JDBC datastore in this
case).
The attached patch addresses this issue by narrowing down the original
SQLException to a specific subtype of StoreException based on the SQLState
carried by the original SQLException.
As a result, the JPA-facade layer can translate the exception to a
org.apache.opejpa.persistence.OptimisticLockException which is derived from
intended javax.persistence.OptimisticLockException.
But this exception can get nested further up the exception translation chain
before it reaches the user application.
So, if an application wants to detect whether the exception is caused by
optimistic consistency violation, one way to do it is
boolean isExpectedException(Throwable t, Class expected) {
if (t == null) return false;
if (expected.isAssignableFrom(t.getClass()))
return true;
if (t.getCause()==t) return false;
return isExpectedException(t.getCause(), expected);
}
and call it from the application code as:
try {
// do some JPA stuff;
} catch (Throwable t) {
if (isExpectedException(t,
javax.persistence.OptimisticLockException.class) {
// do some smart thing to retry/recover
else
// rethrow
}
Notes on the patch:
1. The existing DBDictionary.newStoreException() method did detect
referential integrity violations by analyzing
java.sql.SQLException.getSQLState().
2. This patch generalizes the same logic to other violations such as locking
or duplicate key.
3. The only context available to narrow down the cause is
java.sql.SQLException.getSQLState() -- which is ideally be same across JDBC
drivers and different databases.
But ideals are seldom met. So a new method
public String[] DBDictionary.getKnownErrorCodes(int
storeExceptionType)
is introduced, that can be overwritten by database-specific DBDictionary
derivations.
4. The patch only supplies two error codes for referential integrity and
locking errors.
===============================================================================================
If someone can point me to an enumeration of these (supposedly
database-neutral) error codes returned by
SQLException.getSQLState() that will be of great help.
===============================================================================================
> OptimisticException is thrown instead of OptimisticLockException
> ----------------------------------------------------------------
>
> Key: OPENJPA-462
> URL: https://issues.apache.org/jira/browse/OPENJPA-462
> Project: OpenJPA
> Issue Type: Bug
> Affects Versions: 0.9.7
> Environment: BEA WebLogic Server 10
> Reporter: Ajay Aggarwal
>
> In my application, i wanted to catch
> "javax.persistence.OptimisticLockException" and take appropriate action.
> However I am seeing that instead
> "org.apache.openjpa.util.OptimisticException" is being thrown. I don't want
> my code to become dependent on OpenJPA and would like to see
> OptimisticLockException thrown.
> While discussing in the OpenJPA forums, Patrick suggested that I create a
> JIRA issue for this since its a bug.
> You can see the discussion in the forum under title "OptimisticException
> question" few days ago.
> Below is the stack trace from my application.
> <Nov 30, 2007 9:50:53 AM EST> <Error> <EJB> <BEA-010026> <Exception occurred
> during commit of transaction Name=[EJB
> com.covergence.soa.covapi.sesscfg.SessionConfigBean.getSessionConfig(com.covergence.soa.utils.SerJavaSipMessageType)],Xid=BEA1-00001267875BE126CEB7(64273527),Status=Rolled
> back. [Reason=<2|false|0.9.7> org.apache.openjpa.util.OptimisticException:
> Optimistic locking errors were detected when flushing to the data store. The
> following objects may have been concurrently modified in another transaction:
> [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]],numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds
> since begin=2,seconds
> left=30,SCInfo[ajayProduction+AdminServer]=(state=rolledback),properties=({weblogic.transaction.name=[EJB
>
> com.covergence.soa.covapi.sesscfg.SessionConfigBean.getSessionConfig(com.covergence.soa.utils.SerJavaSipMessageType)]}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=AdminServer+172.30.0.202:7001+ajayProduction+t3+admin+7001+,XAResources={WLStore_ajayProduction__WLS_AdminServer},NonXAResources={})],CoordinatorURL=AdminServer+172.30.0.202:7001+ajayProduction+t3+admin+7001+):
> weblogic.transaction.RollbackException: Optimistic locking errors were
> detected when flushing to the data store. The following objects may have
> been concurrently modified in another transaction:
> [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]
> at
> weblogic.transaction.internal.TransactionImpl.throwRollbackException(TransactionImpl.java:1818)
> at
> weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:333)
> at
> weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:227)
> at
> weblogic.ejb.container.internal.BaseRemoteObject.postInvoke1(BaseRemoteObject.java:606)
> at
> weblogic.ejb.container.internal.StatelessRemoteObject.postInvoke1(StatelessRemoteObject.java:57)
> at
> weblogic.ejb.container.internal.BaseRemoteObject.postInvokeTxRetry(BaseRemoteObject.java:426)
> at
> com.covergence.soa.covapi.sesscfg.SessionConfigBean_4w7egw_SessionConfigImpl.getSessionConfig(SessionConfigBean_4w7egw_SessionConfigImpl.java:76)
> at
> jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
> Source)
> at
> java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
> Source)
> at
> weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:63)
> at
> $Proxy67.getSessionConfig(Lcom.covergence.soa.utils.SerJavaSipMessageType;)Lcom.covergence.ws.callouts.SessionConfigType;(Unknown
> Source)
> at
> com.covergence.soa.ws.server.CallOutsImpl.getSessionConfigType(CallOutsImpl.java:46)
> at
> com.covergence.soa.ws.server.CallOutsImplBase.getSessionPolicy(CallOutsImplBase.java:238)
> at
> jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
> Source)
> at
> java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
> Source)
> at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:50)
> at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:42)
> at
> com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:247)
> at
> com.sun.xml.ws.server.sei.SEIInvokerPipe.process(SEIInvokerPipe.java:97)
> at weblogic.wsee.jaxws.MonitoringPipe.process(MonitoringPipe.java:98)
> at
> com.sun.xml.ws.protocol.soap.ServerMUPipe.process(ServerMUPipe.java:62)
> at
> com.sun.xml.ws.server.WSEndpointImpl$1.process(WSEndpointImpl.java:139)
> at
> com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:153)
> at
> com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:235)
> at
> com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:97)
> at
> weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:36)
> .>
> javax.ejb.EJBException: nested exception is: <2|false|0.9.7>
> org.apache.openjpa.util.OptimisticException: Optimistic locking errors were
> detected when flushing
> to the data store. The following objects may have been concurrently modified
> in another transaction:
> [com.covergence.soa.covapi.userpolicy.User-com.covergence.
> soa.covapi.userpolicy.User-1]<2|false|0.9.7>
> org.apache.openjpa.util.OptimisticException: Optimistic locking errors were
> detected when flushing to the data store. The following objects may have
> been concurrently modified in another transaction:
> [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]
> at
> org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2120)
> at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1970)
> at
> org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1868)
> at
> org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1786)
> at
> weblogic.transaction.internal.ServerSCInfo.doBeforeCompletion(ServerSCInfo.java:1212)
> at
> weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(ServerSCInfo.java:1190)
> at
> weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(ServerSCInfo.java:118)
> at
> weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain(ServerTransactionImpl.java:1299)
> at
> weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare(ServerTransactionImpl.java:2111)
> at
> weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:260)
> at
> weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:227)
> at
> weblogic.ejb.container.internal.BaseRemoteObject.postInvoke1(BaseRemoteObject.java:606)
> at
> weblogic.ejb.container.internal.StatelessRemoteObject.postInvoke1(StatelessRemoteObject.java:57)
> at
> weblogic.ejb.container.internal.BaseRemoteObject.postInvokeTxRetry(BaseRemoteObject.java:426)
> at
> com.covergence.soa.covapi.sesscfg.SessionConfigBean_4w7egw_SessionConfigImpl.getSessionConfig(SessionConfigBean_4w7egw_SessionConfigImpl.java:76)
> at
> jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
> Source)
> at
> java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
> Source)
> at
> weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:63)
> at
> $Proxy67.getSessionConfig(Lcom.covergence.soa.utils.SerJavaSipMessageType;)Lcom.covergence.ws.callouts.SessionConfigType;(Unknown
> Source)
> at
> com.covergence.soa.ws.server.CallOutsImpl.getSessionConfigType(CallOutsImpl.java:46)
> Caused by: <2|false|0.9.7> org.apache.openjpa.util.OptimisticException: An
> optimistic lock violation was detected when flushing object instance
> "com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1"
> to the data store. This indicates that the object was concurrently modified
> in anothertransaction.
> FailedObject:
> com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1
> at
> kodo.jdbc.kernel.BatchingPreparedStatementManager.checkUpdate(BatchingPreparedStatementManager.java:354)
> at
> kodo.jdbc.kernel.BatchingPreparedStatementManager.flushInternal(BatchingPreparedStatementManager.java:208)
> at
> kodo.jdbc.kernel.BatchingPreparedStatementManager.flush(BatchingPreparedStatementManager.java:188)
> at
> kodo.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:90)
> at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:86)
> at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:69)
> at
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:511)
> at
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:127)
> at
> org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:506)
> at
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:127)
> at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1970)
> at
> org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1868)
> at
> org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1786)
> at
> weblogic.transaction.internal.ServerSCInfo.doBeforeCompletion(ServerSCInfo.java:1212)
> at
> weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(ServerSCInfo.java:1190)
> at
> weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(ServerSCInfo.java:118)
> at
> weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain(ServerTransactionImpl.java:1299)
> at
> weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare(ServerTransactionImpl.java:2111)
> at
> weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:260)
> at
> weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:227)
> at
> weblogic.ejb.container.internal.BaseRemoteObject.postInvoke1(BaseRemoteObject.java:606)
> at
> weblogic.ejb.container.internal.StatelessRemoteObject.postInvoke1(StatelessRemoteObject.java:57)
> at
> weblogic.ejb.container.internal.BaseRemoteObject.postInvokeTxRetry(BaseRemoteObject.java:426)
> javax.ejb.EJBException: nested exception is: <2|false|0.9.7>
> org.apache.openjpa.util.OptimisticException: Optimistic locking errors were
> detected when flushing to the data store. The following objects may have
> been concurrently modified in another transaction:
> [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]
> at
> weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:78)
> at
> $Proxy67.getSessionConfig(Lcom.covergence.soa.utils.SerJavaSipMessageType;)Lcom.covergence.ws.callouts.SessionConfigType;(Unknown
> Source)
> at
> com.covergence.soa.ws.server.CallOutsImpl.getSessionConfigType(CallOutsImpl.java:46)
> at
> com.covergence.soa.ws.server.CallOutsImplBase.getSessionPolicy(CallOutsImplBase.java:238)
> at
> jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
> Source)
> at
> java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
> Source)
> at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:50)
> at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:42)
> at
> com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:247)
> at
> com.sun.xml.ws.server.sei.SEIInvokerPipe.process(SEIInvokerPipe.java:97)
> at weblogic.wsee.jaxws.MonitoringPipe.process(MonitoringPipe.java:98)
> at
> com.sun.xml.ws.protocol.soap.ServerMUPipe.process(ServerMUPipe.java:62)
> at
> com.sun.xml.ws.server.WSEndpointImpl$1.process(WSEndpointImpl.java:139)
> at
> com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:153)
> at
> com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:235)
> at
> com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:97)
> at
> weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:36)
> at weblogic.wsee.jaxws.JAXWSServlet.doPost(JAXWSServlet.java:218)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
> at
> weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:226)
> at
> weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:124)
> at
> weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
> at
> weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
> at
> weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3370)
> at
> weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
> at
> weblogic.security.service.SecurityManager.runAs(Lweblogic.security.acl.internal.AuthenticatedSubject;Lweblogic.security.acl.internal.AuthenticatedSubject;Ljava.security.PrivilegedAction;)Ljava.lang.Object;(Unknown
> Source)
> at
> weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2117)
> at
> weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2023)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.