Possible issue with LAZY Loading

#1

Hi,

We need lazy loading for one of our large data sets. When I run currently against both 2.4.2 and 2.4.3_01 the db is always returning everything, including the data marked as Fetch.LAZY. 

I wrote the attached unit test, and then found this: http://www.objectdb.com/database/forum/9

As far as I can tell, my unit test is pretty much identical. Not sure why this doesn't work.

Thanks

Paul.

#2

Maybe I've misread this, is the db pulling that when it asks in the second part of the test? Or should it be empty?

Pretty much I want a unit test that shows the locationlist coming back empty, and then someway of calling so that it comes back populated. I'm uncertain now whether the test I've created is just causing it to be loaded because I accessed it.

#3

Your observation in #2 is correct - LAZY loading doesn't necessarily mean that the data is inaccessible to the application. The additional data is accessible if entity objects are managed by an open EntityManager, but it is fetched lazily when needed.

You do see a difference (in addition to performance differences) when the EntityManager is closed or results are detached. In this case, LAZY data will not be available and will not be fetched either.

ObjectDB Support
#4

Ok, so then I believe Lazy loading is broken, cause if I close the entityManager without calling "getLocationList" which is marked as LAZY, and then try and access them, they all return happily.

#5

LAZY (unlike EAGER) is considered in JPA as a hint and in some cases data is fetched eagerly regardless of the hint. This happens, for example, when ObjectDB uses reflection mode (classes are not enhanced).

In your example, the lazy location collection is loaded eagerly even when the classes are enhanced because of your implementation of the setLocationList method, which iterates over the collection:

    public void setLocationList(List<Location> locationList) {
        for(Location location : locationList) {
            location.setOwningObject(this);
        }
        this.locationList = locationList;
    }

This method is used by ObjectDB to initialize the field with an empty lazy proxy collection (because your application uses JPA property access rather than field access), but then the application forces ObjectDB to load the collection content.

If you change the method to:

    public void setLocationList(List<Location> locationList) {
        this.locationList = locationList;
    }

and enhance the classes - the test will throw NullPointerException as expected because of an attempt to use the unloaded location collection after closing the EntityManager.

ObjectDB Support

Reply