[ 
https://issues.apache.org/jira/browse/OPENJPA-1980?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13879819#comment-13879819
 ] 

Vermeulen commented on OPENJPA-1980:
------------------------------------

I removed my workaround code and ran my tests again and indeed the issue is 
fixed.

> cascade merge tries to insert null into id column in a 4 entity structure (no 
> DetachedStateField)
> -------------------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-1980
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1980
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.1.0
>         Environment: sql server 2008 (express) on Windows 7
>            Reporter: Vermeulen
>            Assignee: Michael Dick
>             Fix For: 2.2.0
>
>         Attachments: openjpa-1980-unittest.zip
>
>
> We use these settings in persistence.xml (useful when entities can be edited 
> by remote clients):
> <property name="openjpa.DetachState" 
> value="fetch-groups(DetachedStateField=false)" />
> <property name="openjpa.AutoDetach" value="commit" />
> We have an object graph of four entities with autogenerated Id columns:
> Event (OneToMany bidirectional) Activity (OneToMany) ProductOrderLine 
> (OneToOne) StringI18N
> All relations are FetchType.EAGER and Cascade.ALL.
> When I add a new Activity (with one new ProductOrderLine with one new 
> StringI18N) to an existing Event and then merge the Event, OpenJPA tries to 
> insert a null value into the StringI18N Id column. This seems to be only 
> detected on transaction commit:
> <openjpa-2.1.0-r422266:1071316 fatal store error> 
> org.apache.openjpa.persistence.RollbackException: The transaction has been 
> rolled back.  See the nested exceptions for details on the errors that 
> occurred.
> FailedObject: entities.booking.StringI18N@2b1682
>       at 
> org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:585)
>       at 
> EventCascadeMergeTest.saveInTransaction(EventCascadeMergeTest.java:83)
>       at 
> EventCascadeMergeTest.cascadeMergeEventImpl(EventCascadeMergeTest.java:72)
>       at 
> EventCascadeMergeTest.testSaveExistingEventWithNewActivityWithNewProductOrderLine(EventCascadeMergeTest.java:35)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>       at java.lang.reflect.Method.invoke(Method.java:597)
>       at 
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
>       at 
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
>       at 
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
>       at 
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
>       at 
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
>       at 
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
>       at 
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
>       at 
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
>       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
>       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
>       at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
>       at 
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
>       at 
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
>       at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
>       at 
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
>       at 
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>       at 
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: <openjpa-2.1.0-r422266:1071316 fatal store error> 
> org.apache.openjpa.persistence.EntityExistsException: The transaction has 
> been rolled back.  See the nested exceptions for details on the errors that 
> occurred.
> FailedObject: entities.booking.StringI18N@2b1682
>       at 
> org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2316)
>       at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2153)
>       at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2051)
>       at 
> org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1969)
>       at 
> org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
>       at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1493)
>       at 
> org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:925)
>       at 
> org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:561)
>       ... 27 more
> Caused by: <openjpa-2.1.0-r422266:1071316 fatal store error> 
> org.apache.openjpa.persistence.EntityExistsException: Cannot insert the value 
> NULL into column 'id', table 'obliprototypeunittest.dbo.booking_StringI18N'; 
> column does not allow nulls. INSERT fails. {prepstmnt 28007854 INSERT INTO 
> booking_StringI18N (id, dutch, english) VALUES (?, ?, ?) [params=?, ?, ?]} 
> [code=515, state=23000]
> FailedObject: entities.booking.StringI18N@2b1682
>       at 
> org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4854)
>       at 
> org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4829)
>       at 
> org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:136)
>       at 
> org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:78)
>       at 
> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:143)
>       at 
> org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:81)
>       at 
> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:99)
>       at 
> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:87)
>       at 
> org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:550)
>       at 
> org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:106)
>       at 
> org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59)
>       at 
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:103)
>       at 
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:76)
>       at 
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:742)
>       at 
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131)
>       ... 34 more
> Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: Cannot insert 
> the value NULL into column 'id', table 
> 'obliprototypeunittest.dbo.booking_StringI18N'; column does not allow nulls. 
> INSERT fails. {prepstmnt 28007854 INSERT INTO booking_StringI18N (id, dutch, 
> english) VALUES (?, ?, ?) [params=?, ?, ?]} [code=515, state=23000]
>       at 
> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:281)
>       at 
> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:257)
>       at 
> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$1000(LoggingConnectionDecorator.java:72)
>       at 
> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:1199)
>       at 
> org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:291)
>       at 
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1776)
>       at 
> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.executeUpdate(PreparedStatementManagerImpl.java:267)
>       at 
> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:118)
>       ... 44 more
> This problem does not occur when:
> - I use a DetachedStateField (unfortunately I have issues with this such as 
> getting stale data from related entities on detach)
> - The Event is new as well.
> - I don't use CascadeType.PERSIST on the Activity.event field. BUT: even 
> though the merge succeeds, I get that 
>      event != event.activities.get(0).event (!!)
> - workaround: manually do the cascade merge between Event and Activities: 
> merge the Event without the new Activities, merge the Activities, then link 
> them to the Event.
> I attached a unit test with the four entities and my persistence.xml (sorry 
> they are not OpenJPA unit tests yet).
> Note that I serialize the entities after detaching (using 
> org.apache.commons.lang.SerializationUtils). If I don't do this I 
> additionally get an IllegalStateException at BrokerImpl.assertOpen
> when I add a new Activity to the List in a detached Event. This problem also 
> does not occur when using a DetachedStateField.



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

Reply via email to