eclipse-ee4j / eclipselink

Eclipselink project
https://eclipse.dev/eclipselink/
Other
202 stars 172 forks source link

Bug 371743 - Fetching Lazy-Fields (Basic-Mapping) causes inconsistent database reload on the whole entity #1932

Open t-beckmann opened 1 year ago

t-beckmann commented 1 year ago

The bug originally reported at https://bugs.eclipse.org/bugs/show_bug.cgi?id=371743 since EclipseLink 2.1.3 exists, still. When triggering a lazy-loaded basic attribute existing changes made to the entity are reset.

That is because the ReadObjectQuery issued at https://github.com/eclipse-ee4j/eclipselink/blob/master/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/queries/FetchGroup.java#L145 does not respect an existing changeset of the entity.

As stated in the comments of the original bug report, this bug effectively renders lazy-loaded basic attributes pretty much unusable.

t-beckmann commented 1 year ago

Unlike the original report, that asked for the code to fetch all lazy-loaded attributes at once, I do believe the correct fix would be to fetch the yet unfetched attribute only.

t-beckmann commented 1 year ago

See also https://stackoverflow.com/a/30320165/9568167.

patric-r commented 1 year ago

Is this still occurring in recent releases? The original bug report as well as stackoverflow mention LOBs - is this limited to LOBs and if not - of what java and sql type are your lazily-fetched Basic-Mapping fields?

t-beckmann commented 1 year ago

Not just LOBs but basic strings mapped to an ordinary varchar column. Last time I checked this behavior was present, still. This was the current version when I filed this report.

patric-r commented 1 year ago

Ah, I did not realize at first that this is a fetch group-related issue.

We disabled fetch group support from the very beginning (ironically for performance reasons) but it's surprising that fetch groups seem to also affect correctness, if this issue holds true.

Are you willing to provide a minimalistic unit test which reproduces the problem?

t-beckmann commented 1 year ago

To me the fetchgroups actually provide a lot flexibility, entity graphs won't work without. Wasn't even aware that can be disabled? Ah, by turning off that weaving option.

Is there an existing test that I could build upon, that has weaving enable? I had a look around the codebase and found the jpa test submodule to be concerned with interface contracts mainly. Advice what to look at would save me some time.

Also I tries running the tests using mvn test and it failed building due to module dependencies. Is there any documentation on how to run the tests? The wiki pages refer to ant and are outdated.

Zuplyx commented 1 year ago

You could adapt this maven project I created for another issue. It has a basic, statically weaved PU and by default uses an in-memory derby DB. I found this approach with an external project to be easier than adapting eclipselink's own unit tests.

t-beckmann commented 11 months ago

jpa-lazy-basic-fields.zip

Thanks @Zuplyx, find attached a minimal reproduction of the issue. The test fails because the changed but not yet persisted newName gets reset to the oldName when the lazyValis fetched by accessing it.

    @Test
    void test() {
        var entity = new MyTestEntity();
        entity.setId(1L);
        entity.setName("oldName");
        entity.setLazy("lazyVal");
        em.persist(entity);
        em.flush();
        em.clear();

        entity = em.find(MyTestEntity.class, 1L);
        Assertions.assertEquals("oldName", entity.getName());
        entity.setName("newName");
        Assertions.assertEquals("newName", entity.getName());
        Assertions.assertEquals("lazyVal", entity.getLazy());
        Assertions.assertEquals("newName", entity.getName());
    }

The last assertion fails.

xtroce commented 4 weeks ago

Any updates on this issue? It's 4 months shy of being 15 years old now...

We also have this problem in our codebase and it makes weaving pretty much unusable for us, while using payara. Which in turn disables almost all optimization annotations afaik. (If that is not the case i'd pretty much like to find out more about how to get this working without having to turn to static weaving)

t-beckmann commented 4 weeks ago

how to get this working without having to turn to static weaving

Sadly static weaving does not solve this from my experience.