[ 
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)

Reply via email to