final PreLoadEvent preLoadEvent,
final PostLoadEvent postLoadEvent) throws HibernateException {
//TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)
final PersistenceContext persistenceContext = session.getPersistenceContext();
EntityEntry entityEntry = persistenceContext.getEntry(entity);
if ( entityEntry == null ) {
throw new AssertionFailure( "possible non-threadsafe access to the session" );
}
EntityPersister persister = entityEntry.getPersister();
Serializable id = entityEntry.getId();
Object[] hydratedState = entityEntry.getLoadedState();
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Resolving associations for %s",
MessageHelper.infoString( persister, id, session.getFactory() )
);
}
Type[] types = persister.getPropertyTypes();
for ( int i = 0; i < hydratedState.length; i++ ) {
final Object value = hydratedState[i];
if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
hydratedState[i] = types[i].resolve( value, session, entity );
}
}
//Must occur after resolving identifiers!
if ( session.isEventSource() ) {
preLoadEvent.setEntity( entity ).setState( hydratedState ).setId( id ).setPersister( persister );
final EventListenerGroup<PreLoadEventListener> listenerGroup = session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.PRE_LOAD );
for ( PreLoadEventListener listener : listenerGroup.listeners() ) {
listener.onPreLoad( preLoadEvent );
}
}
persister.setPropertyValues( entity, hydratedState );
final SessionFactoryImplementor factory = session.getFactory();
if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) {
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Adding entity to second-level cache: %s",
MessageHelper.infoString( persister, id, session.getFactory() )
);
}
Object version = Versioning.getVersion(hydratedState, persister);
CacheEntry entry = new CacheEntry(
hydratedState,
persister,
entityEntry.isLoadedWithLazyPropertiesUnfetched(),
version,
session,
entity
);
CacheKey cacheKey = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
// explicit handling of caching for rows just inserted and then somehow forced to be read
// from the database *within the same transaction*. usually this is done by
// 1) Session#refresh, or
// 2) Session#clear + some form of load
//
// we need to be careful not to clobber the lock here in the cache so that it can be rolled back if need be
if ( session.getPersistenceContext().wasInsertedDuringTransaction( persister, id ) ) {
persister.getCacheAccessStrategy().update(
cacheKey,
persister.getCacheEntryStructure().structure( entry ),
version,
version
);
}
else {
boolean put = persister.getCacheAccessStrategy().putFromLoad(
cacheKey,
persister.getCacheEntryStructure().structure( entry ),
session.getTimestamp(),
version,
useMinimalPuts( session, entityEntry )
);
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() );
}
}
}
boolean isReallyReadOnly = readOnly;
if ( !persister.isMutable() ) {
isReallyReadOnly = true;
}
else {
Object proxy = persistenceContext.getProxy( entityEntry.getEntityKey() );
if ( proxy != null ) {
// there is already a proxy for this impl
// only set the status to read-only if the proxy is read-only
isReallyReadOnly = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().isReadOnly();
}
}
if ( isReallyReadOnly ) {
//no need to take a snapshot - this is a
//performance optimization, but not really
//important, except for entities with huge
//mutable property values
persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
}
else {
//take a snapshot
TypeHelper.deepCopy(
hydratedState,
persister.getPropertyTypes(),
persister.getPropertyUpdateability(),
hydratedState, //after setting values to object, entityMode
session
);
persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
}
persister.afterInitialize(
entity,
entityEntry.isLoadedWithLazyPropertiesUnfetched(),