[ https://issues.apache.org/jira/browse/OPENJPA-2718?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Damian Bułak updated OPENJPA-2718: ---------------------------------- Priority: Critical (was: Major) > ClassCastException during flush > ------------------------------- > > Key: OPENJPA-2718 > URL: https://issues.apache.org/jira/browse/OPENJPA-2718 > Project: OpenJPA > Issue Type: Bug > Components: jpa, kernel > Affects Versions: 2.4.2 > Reporter: Damian Bułak > Priority: Critical > Attachments: openjpa-cascading-bug.zip > > > Assuming I have three entities - Organization, Department and Employee and > Organization has collection of Departments and Department has collection of > employees where each association has CascadeType.ALL, when I open three > transactions within one entity manager session: > In 1st transaction a department is created and persisted > In 2nd transaction an organization is created and previously created > department is fetched from DB and added to organization departments set, then > organization is persisted > In 3rd transaction an employee is created and added to the department created > in 1st transaction, which is again as in 2nd transaction fetched from DB. > The following exception is thrown: > {code} > <openjpa-2.4.2-r422266:1777108 fatal store error> > org.apache.openjpa.persistence.RollbackException: > org.apache.openjpa.kernel.DetachedValueStateManager cannot be cast to > org.apache.openjpa.kernel.StateManagerImpl > at > org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:595) > at > CascadeTestCase.shouldEmployeeBeCascadedFromDepartment(CascadeTestCase.java:30) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) > at > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) > at > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) > at > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) > at > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) > at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) > at > org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) > at > org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) > at org.junit.runners.ParentRunner.run(ParentRunner.java:309) > at > org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) > at > org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) > at > org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) > at > org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) > at > org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) > at > org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) > at > org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) > at > org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) > Caused by: <openjpa-2.4.2-r422266:1777108 nonfatal general error> > org.apache.openjpa.persistence.PersistenceException: > org.apache.openjpa.kernel.DetachedValueStateManager cannot be cast to > org.apache.openjpa.kernel.StateManagerImpl > at > org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2029) > at > org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81) > at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1526) > at > org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:932) > at > org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:571) > ... 30 more > Caused by: java.lang.ClassCastException: > org.apache.openjpa.kernel.DetachedValueStateManager cannot be cast to > org.apache.openjpa.kernel.StateManagerImpl > at > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:134) > at > org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:79) > at > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:100) > at > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:88) > at > org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:550) > at > org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:107) > at > org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59) > at > org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:104) > at > org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:77) > at > org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:731) > at > org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131) > at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2205) > at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2103) > at > org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2021) > ... 34 more > {code} > What I did, I debugged the OpenJPA sources and found that persisting the > organization in the second transaction triggers flush on department however > the department state manager is marked with the FLAG_PRE_FLUSHED flag but > after the whole operation the flag is still active (it should be removed in > StateManagerImpl#afterFlush(int reason) and that's why the employee object > from 3rd transaction is not persisted - the first condition in > StateManagerImpl#preFlush(boolean logical, OpCallbacks call) is false. > Obviously the Employee entity should be persisted since it is added to the > collection with cascading and at the commit time flush should trigger that > operation. > It seems that the problem is very similar to > https://issues.apache.org/jira/projects/OPENJPA/issues/OPENJPA-2360 and > probably has the same root. > I attached a simple test case which reproduces the issue. -- This message was sent by Atlassian JIRA (v6.4.14#64029)