OpenJPA
  1. OpenJPA
  2. OPENJPA-1933

@ElementCollection loose proxytype after serialisation

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 2.0.0, 2.0.1, 2.1.1, 2.2.0
    • Fix Version/s: 2.4.0
    • Component/s: kernel
    • Labels:
      None

      Description

      usually an @ElementCollection field loaded from the database will be created as a org.apache.openjpa.java$.util$.ArrayListProxy.

      After serialisation/deserialisation (with DetachedStateField=true) the List will be recreated as standard java.util.ArrayList.

      This has the bad side effect, that any subsequent add to this ElementCollection will not set the _dirty field in the DetachedStateManager and any changes in the ElementCollection will not get saved to the database.

      1. OPENJPA-1933-test.patch
        9 kB
        Mark Struberg
      2. OPENJPA-1933-test-2.patch
        10 kB
        Mark Struberg
      3. openjpa-reg-tests.tar.gz
        5 kB
        Mark Struberg

        Activity

        Hide
        Albert Lee added a comment -

        Move fix version to 2.3.0 in preparation for 2.2.0 release.

        Show
        Albert Lee added a comment - Move fix version to 2.3.0 in preparation for 2.2.0 release.
        Hide
        Michael Dick added a comment -

        Here's where my story falls apart : org.apache.openjpa.util.Proxies:156
        if (useDSFForUnproxy) {
        // use new 2.0 behavior
        if ((meta != null) && (Boolean.TRUE.equals(meta.usesDetachedState())))

        { // configured to always use and serialize a StateManger, so keep any $proxy return proxy; }

        else

        { // already detached or using DetachedStateField==false or transient, so remove any $proxy return proxy.copy(proxy); }

        }

        With a 2.0 persistence.xml we will check the meta.usesDetachedState() in addition to the DSM and IgnoreDetachedTooLongToTypeCompatibilityOption. I have not fully unraveled that method - there's some room for improvement in this path.

        Sorry you had to hit this particular tangle.

        Show
        Michael Dick added a comment - Here's where my story falls apart : org.apache.openjpa.util.Proxies:156 if (useDSFForUnproxy) { // use new 2.0 behavior if ((meta != null) && (Boolean.TRUE.equals(meta.usesDetachedState()))) { // configured to always use and serialize a StateManger, so keep any $proxy return proxy; } else { // already detached or using DetachedStateField==false or transient, so remove any $proxy return proxy.copy(proxy); } } With a 2.0 persistence.xml we will check the meta.usesDetachedState() in addition to the DSM and IgnoreDetachedTooLongToTypeCompatibilityOption. I have not fully unraveled that method - there's some room for improvement in this path. Sorry you had to hit this particular tangle.
        Hide
        Michael Dick added a comment -

        To answer your question, IgnoreDetachedStateFieldForProxySerialization is only when we replace a proxy field ( so collections, or temporal fields). It doesn't bleed into other parts of the code.

        But you shouldn't have to use it - if you have a DetachedStateManager (that should be some consolation).

        Show
        Michael Dick added a comment - To answer your question, IgnoreDetachedStateFieldForProxySerialization is only when we replace a proxy field ( so collections, or temporal fields). It doesn't bleed into other parts of the code. But you shouldn't have to use it - if you have a DetachedStateManager (that should be some consolation).
        Hide
        Michael Dick added a comment -

        I took a look through the documentation, here's my take.

        If you have a persistence.xml file with version=2.0. The proxies will be removed if DetachedStateManager=true and (IgnoreDetachedStateFieldForProxySerialization=false or is unset). Otherwise the proxies will not be removed.

        If you have a persistence.xml file with version=1.0. The proxies should be serialized if you call EntityManager.clear() prior to serializing. Otherwise (e.g. if you call detach() or detachAll(), or find() ) the proxies will be removed.

        This seems to be the opposite of what you've found (but I haven't thoroughly looked at the tests) - so you're right - we have a fish in our deserialization logic.

        This is a very confusing set of options and we should try to make it clearer in a future release, but for now I think we've at least identified the issue.

        Show
        Michael Dick added a comment - I took a look through the documentation, here's my take. If you have a persistence.xml file with version=2.0. The proxies will be removed if DetachedStateManager=true and (IgnoreDetachedStateFieldForProxySerialization=false or is unset). Otherwise the proxies will not be removed. If you have a persistence.xml file with version=1.0. The proxies should be serialized if you call EntityManager.clear() prior to serializing. Otherwise (e.g. if you call detach() or detachAll(), or find() ) the proxies will be removed. This seems to be the opposite of what you've found (but I haven't thoroughly looked at the tests) - so you're right - we have a fish in our deserialization logic. This is a very confusing set of options and we should try to make it clearer in a future release, but for now I think we've at least identified the issue.
        Hide
        Mark Struberg added a comment -

        omg, pretty heavy to find this issue.

        The reason why it used to work in the openjpa-persistence-jdbc test was due to the old persistende_1.0 schema!
        And in my regression test (as in my real world project) I use the version="2.0" of the persistence.xml schema

        I was able to run the regression test after adding
        <property name="openjpa.Compatibility" value="IgnoreDetachedStateFieldForProxySerialization=true"/>

        Conclusio: there is a fish in our deserialisation logic because the DetachedStateManager doesn't create proxies for Collections, Maps, etc anymore...

        Question: which side effects does using IgnoreDetachedStateFieldForProxySerialization=true have? shudder

        Show
        Mark Struberg added a comment - omg, pretty heavy to find this issue. The reason why it used to work in the openjpa-persistence-jdbc test was due to the old persistende_1.0 schema! And in my regression test (as in my real world project) I use the version="2.0" of the persistence.xml schema I was able to run the regression test after adding <property name="openjpa.Compatibility" value="IgnoreDetachedStateFieldForProxySerialization=true"/> Conclusio: there is a fish in our deserialisation logic because the DetachedStateManager doesn't create proxies for Collections, Maps, etc anymore... Question: which side effects does using IgnoreDetachedStateFieldForProxySerialization=true have? shudder
        Hide
        Mark Struberg added a comment -

        this needs the openjpa-tools being activated first see OPENJPA-1934

        Show
        Mark Struberg added a comment - this needs the openjpa-tools being activated first see OPENJPA-1934
        Hide
        Mark Struberg added a comment -

        puh, pretty hard to reproduce in our test suite. Guess this goes hand in hand with having the enhancer.xml almost unmaintainable in the meantime. The

        As a result, I've created an own openjpa-reg-tests (regression tests) module which contains 1 subproject for each JIRA issue and gets activated with the profile 'reg-tests'.

        Each JIRA issue is clearly reproducable this way and doesn't interfere with other configuration settings.

        Show
        Mark Struberg added a comment - puh, pretty hard to reproduce in our test suite. Guess this goes hand in hand with having the enhancer.xml almost unmaintainable in the meantime. The As a result, I've created an own openjpa-reg-tests (regression tests) module which contains 1 subproject for each JIRA issue and gets activated with the profile 'reg-tests'. Each JIRA issue is clearly reproducable this way and doesn't interfere with other configuration settings.
        Hide
        Mark Struberg added a comment -

        This test shows the problems. After the deserialization, the elementCollectionLazy contains just a java.util.List and not a proxy anymore. Thus, the subsequent adding a value to the ElementCollection will not result in a database update.

        Question: should the proxy should get serialized, or should it only get 'restored' if deserialized again?

        Show
        Mark Struberg added a comment - This test shows the problems. After the deserialization, the elementCollectionLazy contains just a java.util.List and not a proxy anymore. Thus, the subsequent adding a value to the ElementCollection will not result in a database update. Question: should the proxy should get serialized, or should it only get 'restored' if deserialized again?
        Hide
        Mark Struberg added a comment -

        work in progress. probably only a unit test configuration problem...

        Show
        Mark Struberg added a comment - work in progress. probably only a unit test configuration problem...
        Hide
        Mark Struberg added a comment -

        work in progress, maybe only a configuration issue with the unit test...

        Show
        Mark Struberg added a comment - work in progress, maybe only a configuration issue with the unit test...
        Hide
        Mark Struberg added a comment -

        this patch extends a previous test which shows the problem. It currently fails to detach the lazy loaded ElementCollection

        Show
        Mark Struberg added a comment - this patch extends a previous test which shows the problem. It currently fails to detach the lazy loaded ElementCollection
        Hide
        Mark Struberg added a comment -

        This might be a regression of OPENJPA-1571 ?

        Show
        Mark Struberg added a comment - This might be a regression of OPENJPA-1571 ?

          People

          • Assignee:
            Unassigned
            Reporter:
            Mark Struberg
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:

              Development