With lazy property fetching enabled, StandardCacheEntryImpl will internally have inconsistent state. This will result in the lazy property value not being returned when the entity is retrieved from the l2 cache.
The problem seems to be caused by the following:
-
In TwoPhaseLoad#doInitializeEntity the cache entry is built before the FieldInterceptor is injected into the entity (which happens in PojoEntityTuplizer#afterInitialize).
-
In AbstractEntityPersister.StandardCacheEntryHelper#buildCacheEntry EntityPersister#hasUninitializedLazyProperties is used to determine if uninitialized lazy properties are present in the state array. This in turn delegates to PojoEntityTuplizer#hasUninitializedLazyProperties which assumes that an absent FieldInterceptor implies no lazy properties. However, this is wrong, as the FieldInterceptor just hasn't been set yet. So in result, StandardCacheEntryImpl#lazyPropertiesAreUnfetched will be false, but the state array contains lazy markers.
When such a broken cache entry is loaded, the FieldInterceptorImpl will be instantiated with a null set of uninitializedFields causing it to assume that all fields have been initialized and hence returning whatever the entity's default constructor assigns as field value.
|