Damian Bułak created OPENJPA-2718:
-------------------------------------

             Summary: 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
         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