I am about to file a bug but wanted to run this by the experts first. Let's say there is a User entity class that declares 20 lazy collections much like so:
@OneToMany( mappedBy = "owner") @Cascade({CascadeType.REMOVE, CascadeType.DELETE_ORPHAN}) @LazyCollection(LazyCollectionOption.TRUE) @BatchSize(size = 1000) @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) public Set<CustomSpace> getCustomSpaces() In Hibernate 3.3.1.GA if I load ~1000 User entities from second level cache (w/o accessing any of the collections), I'll end up spending 5x time assembling cache entries vs. actually loading de-hydrated state from the cache provider (profiler snapshot attached). Most of the time is spent eagerly assembling CollectionTypes, all of which may or may not be needed during a given Session. So, basically, I'm being penalized for merely declaring OneToMany's. Currently, the only way to avoid this penalty - as far as I can tell - is to complicate the domain model by introducing some number of new entities that will be OneToOne to User; and redistributing collection declarations amongst those. But even that may not help: what if services using the domain model access a variety of collections at different times? IMO a much more scalable approach would be to: * stash serialized states representing collection properties during assembleCacheEntry * call CollectionType.assemble lazily when collection property field is actually accessed (a la lazy properties) Fwiw, a post covering the above in a little more detail can be found here: https://forum.hibernate.org/viewtopic.php?p=2412263#p2412263 -nikita
Merged callees +-------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+-----------------+--------------------+ | Name | Time (ms) | Own Time (ms) | Invocation Count | +-------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+-----------------+--------------------+ | +---org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(LoadEvent, EntityPersister, LoadEventListener$LoadType) | 2,390 100 % | 0 | 999 | | | | | | | | +---org.hibernate.event.def.DefaultLoadEventListener.assembleCacheEntry(CacheEntry, Serializable, EntityPersister, LoadEvent) | 1,796 75 % | 15 | 999 | | | | | | | | | | +---org.hibernate.cache.entry.CacheEntry.assemble(Object, Serializable, EntityPersister, Interceptor, EventSource) | 1,546 65 % | 0 | 999 | | | | | | | | | | | | +---org.hibernate.cache.entry.CacheEntry.assemble(Serializable[], Object, Serializable, EntityPersister, Interceptor, EventSource) | 1,546 65 % | 31 | 999 | | | | | | | | | | | | +---org.hibernate.type.TypeFactory.assemble(Serializable[], Type[], SessionImplementor, Object) | 1,250 52 % | 0 | 999 | | | | | | | | | | | | | | +---org.hibernate.type.CollectionType.assemble(Serializable, SessionImplementor, Object) | 1,109 46 % | 31 | 10,998 | | | | | | | | | | | | | | | | +---org.hibernate.type.CollectionType.resolveKey(Serializable, SessionImplementor, Object) | 875 37 % | 0 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.type.CollectionType.getCollection(Serializable, SessionImplementor, Object) | 875 37 % | 78 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.engine.StatefulPersistenceContext.addUninitializedCollection(CollectionPersister, PersistentCollection, Serializable) | 343 14 % | 0 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.engine.loading.LoadContexts.locateLoadingCollection(CollectionPersister, Serializable) | 203 8 % | 31 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.type.CollectionType.getPersister(SessionImplementor) | 62 3 % | 15 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.engine.CollectionKey.<init>(CollectionPersister, Serializable, EntityMode) | 62 3 % | 15 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.type.SetType.instantiate(SessionImplementor, CollectionPersister, Serializable) | 46 2 % | 15 | 10,499 | | | | | | | | | | | | | | | | | | +---org.hibernate.impl.SessionImpl.getPersistenceContext() | 31 1 % | 15 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.type.CollectionType.initializeImmediately(EntityMode) | 31 1 % | 31 | 10,998 | | | | | | | | | | | | | | | | | | +---org.hibernate.impl.SessionImpl.getEntityMode() | 15 1 % | 15 | 10,998 | | | | | | | | | | | | | | | | +---org.hibernate.type.CollectionType.getPersister(SessionImplementor) | 109 5 % | 15 | 10,998 | | | | | | | | | | | | | | | | +---org.hibernate.type.AbstractType.assemble(Serializable, SessionImplementor, Object) | 93 4 % | 31 | 10,998 | | | | | | | | | | | | | | +---org.hibernate.type.AbstractType.assemble(Serializable, SessionImplementor, Object) | 140 6 % | 46 | 16,489 | | | | | | | | | | | | +---org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(Object, Object[], EntityMode) | 265 11 % | 0 | 999 | | | | | | | | | | +---org.hibernate.persister.entity.AbstractEntityPersister.afterInitialize(Object, boolean, SessionImplementor) | 62 3 % | 0 | 999 | | | | | | | | | | +---org.hibernate.type.TypeFactory.deepCopy(Object[], Type[], boolean[], Object[], SessionImplementor) | 46 2 % | 15 | 999 | | | | | | | | | | +---org.hibernate.impl.SessionImpl.instantiate(EntityPersister, Serializable) | 31 1 % | 0 | 999 | | | | | | | | | | +---org.hibernate.engine.Versioning.getVersion(Object[], EntityPersister) | 31 1 % | 31 | 999 | | | | | | | | | | +---org.hibernate.engine.TwoPhaseLoad.addUninitializedCachedEntity(EntityKey, Object, EntityPersister, LockMode, boolean, Object, SessionImplementor) | 31 1 % | 0 | 999 | | | | | | | | | | +---org.hibernate.event.def.DefaultPostLoadEventListener.onPostLoad(PostLoadEvent) | 15 1 % | 15 | 999 | | | | | | | | | | +---org.hibernate.impl.SessionFactoryImpl.getEntityPersister(String) | 15 1 % | 15 | 999 | | | | | | | | +---org.hibernate.cache.jbc2.entity.TransactionalAccess.get(Object, long) | 359 15 % | 0 | 999 | | | | | | | | +---org.hibernate.cache.entry.StructuredCacheEntry.destructure(Object, SessionFactoryImplementor) | 218 9 % | 15 | 999 | | | | | | | | +---org.hibernate.cache.CacheKey.<init>(Serializable, Type, String, EntityMode, SessionFactoryImplementor) | 15 1 % | 0 | 999 | +-------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+-----------------+--------------------+ Generated by YourKit Java Profiler 8.0.7 May 26, 2009 10:51:14 AM
_______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev