[ 
https://issues.apache.org/jira/browse/OPENJPA-2718?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Damian Bułak updated OPENJPA-2718:
----------------------------------
    Description: 
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 is I debugged the OpenJPA sources and found that persisting the 
organization in the second transaction triggers flush on department entity but 
the department state manager is marked with the FLAG_PRE_FLUSHED flag which 
after the whole operation 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.

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


> 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 is I debugged the OpenJPA sources and found that persisting the 
> organization in the second transaction triggers flush on department entity 
> but the department state manager is marked with the FLAG_PRE_FLUSHED flag 
> which after the whole operation 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