OpenJPA
  1. OpenJPA
  2. OPENJPA-1004

Derived Identity fails when parent id is auto-generated

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.2, 2.0.0-M2
    • Fix Version/s: 2.0.0-M2
    • Component/s: None
    • Labels:
      None
    1. OPENJPA-1004-2.patch
      4 kB
      Fay Wang
    2. OPENJPA-1004-1.patch
      9 kB
      Fay Wang
    3. OPENJPA-1004.patch
      3 kB
      Fay Wang

      Activity

      Hide
      Fay Wang added a comment -

      The PCEnhancer generates pcCopyKeyFieldsToObjectId as following:

      public void pcCopyKeyFieldsToObjectId(Object paramObject)

      { Object localObject; ChildId localChildId = (ChildId)((ObjectId)paramObject).getId(); localChildId.id = this.id; Parent localParent = this.parent; if (localParent != null) localObject = ((PersistenceCapable)localParent).pcFetchObjectId(); localChildId.parent = ((localObject != null) ? ((LongId)localObject).getId() : 0L); }

      Since the parent has generated key, its objectId is null during pre-flush stage, the parent.pcFetchObjectId will throw the exception:

      <openjpa-1.2.1-r752877:753278 fatal user error> org.apache.openjpa.persistence.InvalidStateException: Detected reentrant flush. Make sure your flush-time instance callback methods or event listeners do not invoke any operations that require the in-progress flush to complete.
      at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1904)
      at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1679)
      at org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:524)
      at org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:506)
      at org.apache.openjpa.kernel.StateManagerImpl.fetchObjectId(StateManagerImpl.java:1434)
      at net.company.persistence.Parent.pcFetchObjectId(Parent.java)
      at net.company.persistence.Child.pcCopyKeyFieldsToObjectId(Child.java)

      The proposed fix is to have PCEnhancer generate the following code when parent has generated key:

      public void pcCopyKeyFieldsToObjectId(Object paramObject)

      { ChildId localChildId = (ChildId)((ObjectId)paramObject).getId(); localChildId.id = this.id; localChildId.parent = 0L; }

      The test case then passed.

      Show
      Fay Wang added a comment - The PCEnhancer generates pcCopyKeyFieldsToObjectId as following: public void pcCopyKeyFieldsToObjectId(Object paramObject) { Object localObject; ChildId localChildId = (ChildId)((ObjectId)paramObject).getId(); localChildId.id = this.id; Parent localParent = this.parent; if (localParent != null) localObject = ((PersistenceCapable)localParent).pcFetchObjectId(); localChildId.parent = ((localObject != null) ? ((LongId)localObject).getId() : 0L); } Since the parent has generated key, its objectId is null during pre-flush stage, the parent.pcFetchObjectId will throw the exception: <openjpa-1.2.1-r752877:753278 fatal user error> org.apache.openjpa.persistence.InvalidStateException: Detected reentrant flush. Make sure your flush-time instance callback methods or event listeners do not invoke any operations that require the in-progress flush to complete. at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1904) at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1679) at org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:524) at org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:506) at org.apache.openjpa.kernel.StateManagerImpl.fetchObjectId(StateManagerImpl.java:1434) at net.company.persistence.Parent.pcFetchObjectId(Parent.java) at net.company.persistence.Child.pcCopyKeyFieldsToObjectId(Child.java) The proposed fix is to have PCEnhancer generate the following code when parent has generated key: public void pcCopyKeyFieldsToObjectId(Object paramObject) { ChildId localChildId = (ChildId)((ObjectId)paramObject).getId(); localChildId.id = this.id; localChildId.parent = 0L; } The test case then passed.
      Hide
      Fay Wang added a comment -

      Testcase is attached.

      Show
      Fay Wang added a comment - Testcase is attached.
      Hide
      Pinaki Poddar added a comment -

      Excellent fix Fay for a complex problem.

      If you want a stress test of this stuff – There are some added complexity of generated identity on Oracle platform. There is a documented test in org.apapche.openjpa......oracle.TestAutoCrement.

      Show
      Pinaki Poddar added a comment - Excellent fix Fay for a complex problem. If you want a stress test of this stuff – There are some added complexity of generated identity on Oracle platform. There is a documented test in org.apapche.openjpa......oracle.TestAutoCrement.
      Hide
      Fay Wang added a comment -

      The earlier fix has problem. Although persist works, after persist, the objectId is not set properly, causing subsequent update to fail. The new patch will fix persist/update/delete problem.

      Show
      Fay Wang added a comment - The earlier fix has problem. Although persist works, after persist, the objectId is not set properly, causing subsequent update to fail. The new patch will fix persist/update/delete problem.
      Hide
      Knut-Håvard Aksnes added a comment -

      Are there any workarounds/fixes available for Geronimo 1.2.x?
      I am bitten severely by this bug or a close relative using Geronimo 2.2.1 which are using 1.2.2

      Show
      Knut-Håvard Aksnes added a comment - Are there any workarounds/fixes available for Geronimo 1.2.x? I am bitten severely by this bug or a close relative using Geronimo 2.2.1 which are using 1.2.2
      Hide
      Michael Dick added a comment -

      I haven't looked at how feasible it would be to migrate this fix to 1.2.x, and might not get a chance to really look at it until after the 2.1.0 release.

      If you're familiar with maven & svn could you try building the change on 1.2.x? I'm not sure how to install a custom version of OpenJPA into geronimo, but there should be a way.

      Show
      Michael Dick added a comment - I haven't looked at how feasible it would be to migrate this fix to 1.2.x, and might not get a chance to really look at it until after the 2.1.0 release. If you're familiar with maven & svn could you try building the change on 1.2.x? I'm not sure how to install a custom version of OpenJPA into geronimo, but there should be a way.

        People

        • Assignee:
          Unassigned
          Reporter:
          Fay Wang
        • Votes:
          0 Vote for this issue
          Watchers:
          1 Start watching this issue

          Dates

          • Created:
            Updated:
            Resolved:

            Development