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)