Hi,
I looked a little more into the Hibernate code and this is what I have found so far:
1- The following is valid for a load of an object from class A that does not have objects of class B (the collection or set in this case) nor of class C (mapped by a one-to-one relationship). 2- When Hibernate is hydrating object A and arrives to the property that holds a reference to class C: 2a- Tries to resolve this type 2b- Eventually it will run a query (EntityLoader.doQuery()) which will return no data as there is no record in C for this particular ID 2c- Then in Loader.initializeEntitiesAndCollections(), as there won't be any objects to hydrate (properties of class C), it won't call the TwoPhaseLoad.initializeEntity() method for class C. This last method is where objects of class C are usually cached in the C cache, but it will never happen (no entry will be added to the cache) for those records in A that do not have a corresponding record in C. 3- When Hibernate is hydrating object A and arrives to the property that hold a reference to class B: 3a- Will resolve the type (but won't load the collection data yet) 4- After object A is fully hydrated, it will eventually call StatefulPersistenceContext.initializeNonLazyCollections() which at some point will do Loader.endCollectionLoad(), which will call CollectionLoadContext.endLoadingCollections(), which ultimately will call addCollectionToCache(). This last method will add a collection (even an empty one as in the case when there are no records in B) to the B cache.
In the end what happens is that collections are kind-of post processed and initialized after the "parent" object, and during this initialization they are cached (no matter which values - if any - they have). On the other hand, one to one relationships do not have this, and as soon as the "child" record is not there nothing else gets done and no caching is done.
I believe one-to-one relationships should also be cached in the same way as collections are dealt with, that is, even if the "child" (for lacking a better name) is not there, there should still be a cache entry with the ID of the "parent" record.
Does anyone know if I am doing something wrong? Is this the expected behavior or could my suggestion be applied as an enhancement?
Please let me know, this is causing us some performance issues.
Regards,
Cris.
|