You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Damian Bułak (JIRA)" <ji...@apache.org> on 2017/09/28 06:05:00 UTC

[jira] [Updated] (OPENJPA-2718) ClassCastException during flush

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