For bytecode enhanced entities with lazy non-proxy ManyToOne properties, the foreign key column could be fetched with default fetchgroup like simple properties. This would reduce the number of SQL queries sent to the persistence store. Currently for n lazy ManyToOne properties, n SQL queries are sent like:
select c.parent_id FROM child_table c where c.id = ?;
This is even true if the Child entity from child_table has been received from 2nd level cache itself and ManyToOne properties had gotten initialized in a different Session before and could hence also be present in L2 cache. The 2nd level cache does not get updated with initialized ManyToOne properties.
org.hibernate.persister.entity.AbstractEntityPersister.initializeLazyProperty(String, Object, SharedSessionContractImplementor)
...
final Object ce = CacheHelper.fromSharedCache( session, cacheKey, cacheAccess );
if ( ce != null ) {
final CacheEntry cacheEntry =
(CacheEntry) getCacheEntryStructure().destructure( ce, factory );
final Object initializedValue =
initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
if (initializedValue != LazyPropertyInitializer.UNFETCHED_PROPERTY) {
return initializedValue;
}
}
...
The early exit return in AbstractEntityPersister.java line 1101 never executes for ManyToOne properties. I'd suggest to either
- update the L2 cache on ManyToOne lazy initialization so it can later be fulle received from L2 cache without SQL interaction
- or fetch FK eagerly in default fetch group like other simple properties and add it to L2 cache.
|