misc cleanups to default events listeners
This commit is contained in:
parent
bd57af6d97
commit
49fb2dce8a
|
@ -71,7 +71,7 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
|
||||
LOG.trace( "Flushing session" );
|
||||
|
||||
EventSource session = event.getSession();
|
||||
final EventSource session = event.getSession();
|
||||
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
session.getInterceptor().preFlush( persistenceContext.managedEntitiesIterator() );
|
||||
|
@ -139,14 +139,20 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
//safe from concurrent modification because of how concurrentEntries() is implemented on IdentityMap
|
||||
for ( Map.Entry<Object,EntityEntry> me : persistenceContext.reentrantSafeEntityEntries() ) {
|
||||
// for ( Map.Entry me : IdentityMap.concurrentEntries( persistenceContext.getEntityEntries() ) ) {
|
||||
EntityEntry entry = me.getValue();
|
||||
Status status = entry.getStatus();
|
||||
if ( status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY ) {
|
||||
final EntityEntry entry = me.getValue();
|
||||
if ( flushable( entry ) ) {
|
||||
cascadeOnFlush( session, entry.getPersister(), me.getKey(), context );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean flushable(EntityEntry entry) {
|
||||
final Status status = entry.getStatus();
|
||||
return status == Status.MANAGED
|
||||
|| status == Status.SAVING
|
||||
|| status == Status.READ_ONLY;
|
||||
}
|
||||
|
||||
private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, PersistContext anything)
|
||||
throws HibernateException {
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
|
@ -209,9 +215,8 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
for ( Map.Entry<Object,EntityEntry> me : entityEntries ) {
|
||||
// Update the status of the object and if necessary, schedule an update
|
||||
|
||||
EntityEntry entry = me.getValue();
|
||||
Status status = entry.getStatus();
|
||||
|
||||
final EntityEntry entry = me.getValue();
|
||||
final Status status = entry.getStatus();
|
||||
|
||||
if ( status != Status.LOADING && status != Status.GONE ) {
|
||||
entityEvent = createOrReuseEventInstance( entityEvent, source, me.getKey(), entry );
|
||||
|
@ -238,15 +243,15 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
EventSource source,
|
||||
Object key,
|
||||
EntityEntry entry) {
|
||||
FlushEntityEvent entityEvent = possiblyValidExistingInstance;
|
||||
if ( entityEvent == null || (! entityEvent.isAllowedToReuse() ) ) {
|
||||
final FlushEntityEvent entityEvent = possiblyValidExistingInstance;
|
||||
if ( entityEvent == null || !entityEvent.isAllowedToReuse() ) {
|
||||
//need to create a new instance
|
||||
entityEvent = new FlushEntityEvent( source, key, entry );
|
||||
return new FlushEntityEvent( source, key, entry );
|
||||
}
|
||||
else {
|
||||
entityEvent.resetAndReuseEventInstance( key, entry );
|
||||
return entityEvent;
|
||||
}
|
||||
return entityEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,8 +356,8 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
try {
|
||||
jdbcCoordinator.flushBeginning();
|
||||
persistenceContext.setFlushing( true );
|
||||
// we need to lock the collection caches before executing entity inserts/updates in order to
|
||||
// account for bi-directional associations
|
||||
// we need to lock the collection caches before executing entity inserts/updates
|
||||
// in order to account for bidirectional associations
|
||||
final ActionQueue actionQueue = session.getActionQueue();
|
||||
actionQueue.prepareActions();
|
||||
actionQueue.executeActions();
|
||||
|
|
|
@ -42,6 +42,7 @@ import static org.hibernate.engine.internal.Versioning.getVersion;
|
|||
import static org.hibernate.engine.internal.Versioning.seedVersion;
|
||||
import static org.hibernate.generator.EventType.INSERT;
|
||||
import static org.hibernate.id.IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR;
|
||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||
|
||||
/**
|
||||
* A convenience base class for listeners responding to save events.
|
||||
|
@ -115,7 +116,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
|
||||
|
||||
final EntityPersister persister = source.getEntityPersister( entityName, entity );
|
||||
Generator generator = persister.getGenerator();
|
||||
final Generator generator = persister.getGenerator();
|
||||
if ( !generator.generatedOnExecution() ) {
|
||||
final Object generatedId = ( (BeforeExecutionGenerator) generator ).generate( source, entity, null, INSERT );
|
||||
if ( generatedId == null ) {
|
||||
|
@ -169,7 +170,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
boolean requiresImmediateIdAccess) {
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev( "Saving {0}", MessageHelper.infoString( persister, id, source.getFactory() ) );
|
||||
LOG.tracev( "Saving {0}", infoString( persister, id, source.getFactory() ) );
|
||||
}
|
||||
|
||||
final EntityKey key = entityKey( entity, id, persister, useIdentityColumn, source );
|
||||
|
@ -250,13 +251,13 @@ public abstract class AbstractSaveEventListener<C>
|
|||
|
||||
final Object id = key == null ? null : key.getIdentifier();
|
||||
|
||||
boolean shouldDelayIdentityInserts = !source.isTransactionInProgress() && !requiresImmediateIdAccess;
|
||||
final boolean shouldDelayIdentityInserts = !source.isTransactionInProgress() && !requiresImmediateIdAccess;
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
|
||||
// Put a placeholder in entries, so we don't recurse back and try to save() the
|
||||
// same object again. QUESTION: should this be done before onSave() is called?
|
||||
// likewise, should it be done before onUpdate()?
|
||||
EntityEntry original = persistenceContext.addEntry(
|
||||
final EntityEntry original = persistenceContext.addEntry(
|
||||
entity,
|
||||
Status.SAVING,
|
||||
null,
|
||||
|
@ -287,9 +288,9 @@ public abstract class AbstractSaveEventListener<C>
|
|||
|
||||
final Object finalId = handleGeneratedId( useIdentityColumn, id, insert );
|
||||
|
||||
EntityEntry newEntry = persistenceContext.getEntry( entity );
|
||||
final EntityEntry newEntry = persistenceContext.getEntry( entity );
|
||||
if ( newEntry != original ) {
|
||||
EntityEntryExtraState extraState = newEntry.getExtraState( EntityEntryExtraState.class );
|
||||
final EntityEntryExtraState extraState = newEntry.getExtraState( EntityEntryExtraState.class );
|
||||
if ( extraState == null ) {
|
||||
newEntry.addExtraState( original.getExtraState( EntityEntryExtraState.class ) );
|
||||
}
|
||||
|
@ -301,7 +302,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
private static Object handleGeneratedId(boolean useIdentityColumn, Object id, AbstractEntityInsertAction insert) {
|
||||
if ( useIdentityColumn && insert.isEarlyInsert() ) {
|
||||
if ( insert instanceof EntityIdentityInsertAction ) {
|
||||
Object generatedId = ((EntityIdentityInsertAction) insert).getGeneratedId();
|
||||
final Object generatedId = ((EntityIdentityInsertAction) insert).getGeneratedId();
|
||||
insert.handleNaturalIdPostSaveNotifications( generatedId );
|
||||
return generatedId;
|
||||
}
|
||||
|
@ -318,8 +319,8 @@ public abstract class AbstractSaveEventListener<C>
|
|||
}
|
||||
|
||||
private Object[] cloneAndSubstituteValues(Object entity, EntityPersister persister, C context, EventSource source, Object id) {
|
||||
Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap(context), source );
|
||||
Type[] types = persister.getPropertyTypes();
|
||||
final Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( context ), source );
|
||||
final Type[] types = persister.getPropertyTypes();
|
||||
|
||||
boolean substitute = substituteValuesIfNecessary( entity, id, values, persister, source );
|
||||
if ( persister.hasCollections() ) {
|
||||
|
@ -349,7 +350,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
EventSource source,
|
||||
boolean shouldDelayIdentityInserts) {
|
||||
if ( useIdentityColumn ) {
|
||||
EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
|
||||
final EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
|
||||
values,
|
||||
entity,
|
||||
persister,
|
||||
|
@ -396,7 +397,7 @@ public abstract class AbstractSaveEventListener<C>
|
|||
Object[] values,
|
||||
Type[] types,
|
||||
EventSource source) {
|
||||
WrapVisitor visitor = new WrapVisitor( entity, id, source );
|
||||
final WrapVisitor visitor = new WrapVisitor( entity, id, source );
|
||||
// substitutes into values by side effect
|
||||
visitor.processEntityPropertyValues( values, types );
|
||||
return visitor.isSubstitutionRequired();
|
||||
|
|
|
@ -131,17 +131,17 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
}
|
||||
|
||||
private static void deleteOwnedCollections(Type type, Object key, EventSource session) {
|
||||
MappingMetamodelImplementor mappingMetamodel = session.getFactory().getMappingMetamodel();
|
||||
ActionQueue actionQueue = session.getActionQueue();
|
||||
final MappingMetamodelImplementor mappingMetamodel = session.getFactory().getMappingMetamodel();
|
||||
final ActionQueue actionQueue = session.getActionQueue();
|
||||
if ( type.isCollectionType() ) {
|
||||
String role = ( (CollectionType) type ).getRole();
|
||||
CollectionPersister persister = mappingMetamodel.getCollectionDescriptor(role);
|
||||
final String role = ( (CollectionType) type ).getRole();
|
||||
final CollectionPersister persister = mappingMetamodel.getCollectionDescriptor(role);
|
||||
if ( !persister.isInverse() ) {
|
||||
actionQueue.addAction( new CollectionRemoveAction( persister, key, session ) );
|
||||
}
|
||||
}
|
||||
else if ( type.isComponentType() ) {
|
||||
Type[] subtypes = ( (CompositeType) type ).getSubtypes();
|
||||
final Type[] subtypes = ( (CompositeType) type ).getSubtypes();
|
||||
for ( Type subtype : subtypes ) {
|
||||
deleteOwnedCollections( subtype, key, session );
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
private void delete(DeleteEvent event, DeleteContext transientEntities) {
|
||||
final PersistenceContext persistenceContext = event.getSession().getPersistenceContextInternal();
|
||||
final Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
|
||||
EntityEntry entityEntry = persistenceContext.getEntry( entity );
|
||||
final EntityEntry entityEntry = persistenceContext.getEntry( entity );
|
||||
if ( entityEntry == null ) {
|
||||
deleteTransientInstance( event, transientEntities, entity );
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
|
||||
final EventSource source = event.getSession();
|
||||
|
||||
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
|
||||
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
|
||||
if ( ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
|
||||
deleteTransientEntity( source, entity, persister, transientEntities );
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
|
||||
final Object version = persister.getVersion( entity );
|
||||
|
||||
EntityEntry entityEntry = persistenceContext.addEntity(
|
||||
final EntityEntry entityEntry = persistenceContext.addEntity(
|
||||
entity,
|
||||
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
|
||||
persister.getValues( entity ),
|
||||
|
@ -214,18 +214,19 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
|| source.getPersistenceContextInternal()
|
||||
.containsDeletedUnloadedEntityKey( entityEntry.getEntityKey() ) ) {
|
||||
LOG.trace( "Object was already deleted" );
|
||||
return;
|
||||
}
|
||||
delete(
|
||||
event,
|
||||
transientEntities,
|
||||
source,
|
||||
entity,
|
||||
entityEntry.getPersister(),
|
||||
entityEntry.getId(),
|
||||
entityEntry.getVersion(),
|
||||
entityEntry
|
||||
);
|
||||
else {
|
||||
delete(
|
||||
event,
|
||||
transientEntities,
|
||||
source,
|
||||
entity,
|
||||
entityEntry.getPersister(),
|
||||
entityEntry.getId(),
|
||||
entityEntry.getVersion(),
|
||||
entityEntry
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void delete(
|
||||
|
@ -330,12 +331,13 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
EntityPersister persister,
|
||||
DeleteContext transientEntities) {
|
||||
LOG.handlingTransientEntity();
|
||||
if ( !transientEntities.add( entity ) ) {
|
||||
LOG.trace( "Already handled transient entity; skipping" );
|
||||
return;
|
||||
if ( transientEntities.add( entity ) ) {
|
||||
cascadeBeforeDelete( session, persister, entity, transientEntities );
|
||||
cascadeAfterDelete( session, persister, entity, transientEntities );
|
||||
}
|
||||
else {
|
||||
LOG.trace( "Already handled transient entity; skipping" );
|
||||
}
|
||||
cascadeBeforeDelete( session, persister, entity, transientEntities );
|
||||
cascadeAfterDelete( session, persister, entity, transientEntities );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -128,10 +128,11 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
|
||||
final Object entity = event.getEntity();
|
||||
final EntityEntry entry = event.getEntityEntry();
|
||||
final EventSource session = event.getSession();
|
||||
|
||||
final boolean mightBeDirty = entry.requiresDirtyCheck( entity );
|
||||
|
||||
final Object[] values = getValues( entity, entry, mightBeDirty, event.getSession() );
|
||||
final Object[] values = getValues( entity, entry, mightBeDirty, session );
|
||||
|
||||
event.setPropertyValues( values );
|
||||
|
||||
|
@ -153,7 +154,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
// Search for collections by reachability, updating their role.
|
||||
// We don't want to touch collections reachable from a deleted object
|
||||
if ( persister.hasCollections() ) {
|
||||
new FlushVisitor(event.getSession(), entity )
|
||||
new FlushVisitor( session, entity )
|
||||
.processEntityPropertyValues( values, persister.getPropertyTypes() );
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +195,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
// because collections need wrapping but changes to _them_
|
||||
// don't dirty the container. Also, for versioned data, we
|
||||
// need to wrap before calling searchForDirtyCollections
|
||||
WrapVisitor visitor = new WrapVisitor( event.getEntity(), entry.getId() , event.getSession() );
|
||||
final WrapVisitor visitor = new WrapVisitor( event.getEntity(), entry.getId(), event.getSession() );
|
||||
// substitutes into values by side effect
|
||||
visitor.processEntityPropertyValues( values, persister.getPropertyTypes() );
|
||||
return visitor.isSubstitutionRequired();
|
||||
|
@ -205,7 +206,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
|
||||
private boolean isUpdateNecessary(final FlushEntityEvent event, final boolean mightBeDirty) {
|
||||
EntityEntry entry = event.getEntityEntry();
|
||||
final EntityEntry entry = event.getEntityEntry();
|
||||
if ( mightBeDirty || entry.getStatus() == Status.DELETED ) {
|
||||
// compare to cached state (ignoring collections unless versioned)
|
||||
dirtyCheck( event );
|
||||
|
@ -213,11 +214,12 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
processIfSelfDirtinessTracker( event.getEntity(), SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
|
||||
EventSource source = event.getSession();
|
||||
final Object entity = event.getEntity();
|
||||
processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
|
||||
final EventSource source = event.getSession();
|
||||
source.getFactory()
|
||||
.getCustomEntityDirtinessStrategy()
|
||||
.resetDirty( event.getEntity(), entry.getPersister(), source );
|
||||
.resetDirty( entity, entry.getPersister(), source );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -255,9 +257,9 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
values,
|
||||
dirtyProperties,
|
||||
event.hasDirtyCollection(),
|
||||
status == Status.DELETED && !entry.isModifiableEntity() ?
|
||||
persister.getValues( entity ) :
|
||||
entry.getLoadedState(),
|
||||
status == Status.DELETED && !entry.isModifiableEntity()
|
||||
? persister.getValues( entity )
|
||||
: entry.getLoadedState(),
|
||||
entry.getVersion(),
|
||||
nextVersion,
|
||||
entity,
|
||||
|
@ -384,10 +386,10 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
* Convenience method to retrieve an entities next version value
|
||||
*/
|
||||
private Object getNextVersion(FlushEntityEvent event) throws HibernateException {
|
||||
EntityEntry entry = event.getEntityEntry();
|
||||
EntityPersister persister = entry.getPersister();
|
||||
final EntityEntry entry = event.getEntityEntry();
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
if ( persister.isVersioned() ) {
|
||||
Object[] values = event.getPropertyValues();
|
||||
final Object[] values = event.getPropertyValues();
|
||||
if ( entry.isBeingReplicated() ) {
|
||||
return getVersion( values, persister );
|
||||
}
|
||||
|
@ -402,7 +404,6 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isVersionIncrementRequired(FlushEntityEvent event, EntityEntry entry) {
|
||||
|
@ -432,9 +433,10 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
|
||||
private boolean hasDirtyCollections(FlushEntityEvent event) {
|
||||
EntityPersister persister = event.getEntityEntry().getPersister();
|
||||
if ( isCollectionDirtyCheckNecessary( persister, event.getEntityEntry().getStatus() ) ) {
|
||||
DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor(
|
||||
final EntityEntry entityEntry = event.getEntityEntry();
|
||||
final EntityPersister persister = entityEntry.getPersister();
|
||||
if ( isCollectionDirtyCheckNecessary( persister, entityEntry.getStatus() ) ) {
|
||||
final DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor(
|
||||
event.getEntity(),
|
||||
event.getSession(),
|
||||
persister.getPropertyVersionability()
|
||||
|
@ -576,8 +578,8 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
}
|
||||
}
|
||||
EventSource session = event.getSession();
|
||||
DirtyCheckContextImpl context = new DirtyCheckContextImpl();
|
||||
final EventSource session = event.getSession();
|
||||
final DirtyCheckContextImpl context = new DirtyCheckContextImpl();
|
||||
session.getFactory().getCustomEntityDirtinessStrategy()
|
||||
.findDirty( event.getEntity(), event.getEntityEntry().getPersister(), session, context );
|
||||
return context.found;
|
||||
|
@ -675,13 +677,10 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
}
|
||||
|
||||
private static Object[] getDatabaseSnapshot(
|
||||
EntityPersister persister,
|
||||
Object id,
|
||||
SessionImplementor session) {
|
||||
private static Object[] getDatabaseSnapshot(EntityPersister persister, Object id, SessionImplementor session) {
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
if ( persister.isSelectBeforeUpdateRequired() ) {
|
||||
Object[] snapshot = persistenceContext.getDatabaseSnapshot( id, persister );
|
||||
final Object[] snapshot = persistenceContext.getDatabaseSnapshot( id, persister );
|
||||
if ( snapshot == null ) {
|
||||
//do we even really need this? the update will fail anyway....
|
||||
final StatisticsImplementor statistics = session.getFactory().getStatistics();
|
||||
|
|
|
@ -24,6 +24,8 @@ import org.hibernate.pretty.MessageHelper;
|
|||
import org.hibernate.sql.results.internal.ResultsHelper;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import static org.hibernate.pretty.MessageHelper.collectionInfoString;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -34,35 +36,25 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
* called by a collection that wants to initialize itself
|
||||
*/
|
||||
public void onInitializeCollection(InitializeCollectionEvent event) throws HibernateException {
|
||||
PersistentCollection<?> collection = event.getCollection();
|
||||
SessionImplementor source = event.getSession();
|
||||
final PersistentCollection<?> collection = event.getCollection();
|
||||
final SessionImplementor source = event.getSession();
|
||||
|
||||
CollectionEntry ce = source.getPersistenceContextInternal().getCollectionEntry( collection );
|
||||
final CollectionEntry ce = source.getPersistenceContextInternal().getCollectionEntry( collection );
|
||||
if ( ce == null ) {
|
||||
throw new HibernateException( "collection was evicted" );
|
||||
}
|
||||
if ( !collection.wasInitialized() ) {
|
||||
final CollectionPersister ceLoadedPersister = ce.getLoadedPersister();
|
||||
final CollectionPersister loadedPersister = ce.getLoadedPersister();
|
||||
final Object loadedKey = ce.getLoadedKey();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Initializing collection {0}",
|
||||
MessageHelper.collectionInfoString(
|
||||
ceLoadedPersister,
|
||||
collection,
|
||||
ce.getLoadedKey(),
|
||||
source
|
||||
)
|
||||
collectionInfoString( loadedPersister, collection, loadedKey, source )
|
||||
);
|
||||
LOG.trace( "Checking second-level cache" );
|
||||
}
|
||||
|
||||
final boolean foundInCache = initializeCollectionFromCache(
|
||||
ce.getLoadedKey(),
|
||||
ceLoadedPersister,
|
||||
collection,
|
||||
source
|
||||
);
|
||||
|
||||
final boolean foundInCache = initializeCollectionFromCache( loadedKey, loadedPersister, collection, source );
|
||||
if ( foundInCache ) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Collection initialized from cache" );
|
||||
|
@ -72,17 +64,15 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Collection not cached" );
|
||||
}
|
||||
ceLoadedPersister.initialize( ce.getLoadedKey(), source );
|
||||
handlePotentiallyEmptyCollection( collection, source, ce, ceLoadedPersister );
|
||||
loadedPersister.initialize( loadedKey, source );
|
||||
handlePotentiallyEmptyCollection( collection, source, ce, loadedPersister );
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Collection initialized" );
|
||||
}
|
||||
|
||||
final StatisticsImplementor statistics = source.getFactory().getStatistics();
|
||||
if ( statistics.isStatisticsEnabled() ) {
|
||||
statistics.fetchCollection(
|
||||
ceLoadedPersister.getRole()
|
||||
);
|
||||
statistics.fetchCollection( loadedPersister.getRole() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +82,12 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
PersistentCollection<?> collection,
|
||||
SessionImplementor source,
|
||||
CollectionEntry ce,
|
||||
CollectionPersister ceLoadedPersister) {
|
||||
CollectionPersister loadedPersister) {
|
||||
if ( !collection.wasInitialized() ) {
|
||||
collection.initializeEmptyCollection( ceLoadedPersister );
|
||||
collection.initializeEmptyCollection( loadedPersister );
|
||||
ResultsHelper.finalizeCollectionLoading(
|
||||
source.getPersistenceContext(),
|
||||
ceLoadedPersister,
|
||||
loadedPersister,
|
||||
collection,
|
||||
ce.getLoadedKey(),
|
||||
true
|
||||
|
@ -142,16 +132,10 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
final StatisticsImplementor statistics = factory.getStatistics();
|
||||
if ( statistics.isStatisticsEnabled() ) {
|
||||
if ( ce == null ) {
|
||||
statistics.collectionCacheMiss(
|
||||
persister.getNavigableRole(),
|
||||
cacheAccessStrategy.getRegion().getName()
|
||||
);
|
||||
statistics.collectionCacheMiss( persister.getNavigableRole(), cacheAccessStrategy.getRegion().getName() );
|
||||
}
|
||||
else {
|
||||
statistics.collectionCacheHit(
|
||||
persister.getNavigableRole(),
|
||||
cacheAccessStrategy.getRegion().getName()
|
||||
);
|
||||
statistics.collectionCacheHit( persister.getNavigableRole(), cacheAccessStrategy.getRegion().getName() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +143,7 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
return false;
|
||||
}
|
||||
|
||||
CollectionCacheEntry cacheEntry = (CollectionCacheEntry)
|
||||
final CollectionCacheEntry cacheEntry = (CollectionCacheEntry)
|
||||
persister.getCacheEntryStructure().destructure( ce, factory );
|
||||
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
|
|||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||
|
||||
/**
|
||||
* Defines the default load event listeners used by hibernate for loading entities
|
||||
|
@ -63,11 +64,16 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( persister == null ) {
|
||||
throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() );
|
||||
}
|
||||
checkId( event, loadType, persister );
|
||||
doOnLoad( persister, event, loadType );
|
||||
}
|
||||
|
||||
private void checkId(LoadEvent event, LoadType loadType, EntityPersister persister) {
|
||||
final Object id = event.getEntityId();
|
||||
if ( !persister.getIdentifierMapping().getJavaType().isInstance( id )
|
||||
&& !( id instanceof DelayedPostInsertIdentifier ) ) {
|
||||
final Class<?> idClass = persister.getIdentifierType().getReturnedClass();
|
||||
if ( handleIdType( persister, event, loadType, idClass) ) {
|
||||
if ( handleIdType( persister, event, loadType, idClass ) ) {
|
||||
throw new TypeMismatchException(
|
||||
"Supplied id had wrong type: entity '" + persister.getEntityName()
|
||||
+ "' has id type '" + idClass
|
||||
|
@ -75,7 +81,6 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
);
|
||||
}
|
||||
}
|
||||
doOnLoad( persister, event, loadType );
|
||||
}
|
||||
|
||||
protected EntityPersister getPersister(final LoadEvent event) {
|
||||
|
@ -193,7 +198,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( session.getPersistenceContextInternal().getEntry( event.getInstanceToLoad() ) != null ) {
|
||||
throw new PersistentObjectException(
|
||||
"attempted to load into an instance that was already associated with the session: "
|
||||
+ MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
+ infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), session);
|
||||
|
@ -227,7 +232,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Loading entity: {0}",
|
||||
MessageHelper.infoString( persister, event.getEntityId(), persister.getFactory() )
|
||||
infoString( persister, event.getEntityId(), persister.getFactory() )
|
||||
);
|
||||
}
|
||||
if ( hasBytecodeProxy( persister, options ) ) {
|
||||
|
@ -519,19 +524,20 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
* @return The loaded entity, or null.
|
||||
*/
|
||||
private Object doLoad(LoadEvent event, EntityPersister persister, EntityKey keyToLoad, LoadType options) {
|
||||
final EventSource session = event.getSession();
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Attempting to resolve: {0}",
|
||||
MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
|
||||
infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
|
||||
if ( event.getSession().getPersistenceContextInternal()
|
||||
.containsDeletedUnloadedEntityKey( keyToLoad ) ) {
|
||||
if ( session.getPersistenceContextInternal().containsDeletedUnloadedEntityKey( keyToLoad ) ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
PersistenceContextEntry persistenceContextEntry
|
||||
final PersistenceContextEntry persistenceContextEntry
|
||||
= CacheEntityLoaderHelper.INSTANCE.loadFromSessionCache( event, keyToLoad, options );
|
||||
final Object entity = persistenceContextEntry.getEntity();
|
||||
if ( entity != null ) {
|
||||
|
@ -573,7 +579,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Resolved object in second-level cache: {0}",
|
||||
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
return entity;
|
||||
|
@ -582,7 +588,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Object not resolved in any cache: {0}",
|
||||
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
infoString( persister, event.getEntityId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
return loadFromDatasource( event, persister );
|
||||
|
|
|
@ -56,9 +56,9 @@ public class DefaultLockEventListener extends AbstractLockUpgradeEventListener i
|
|||
LOG.explicitSkipLockedLockCombo();
|
||||
}
|
||||
|
||||
SessionImplementor source = event.getSession();
|
||||
final SessionImplementor source = event.getSession();
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
|
||||
final Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
|
||||
//TODO: if object was an uninitialized proxy, this is inefficient,
|
||||
// resulting in two SQL selects
|
||||
|
||||
|
@ -78,7 +78,7 @@ public class DefaultLockEventListener extends AbstractLockUpgradeEventListener i
|
|||
}
|
||||
|
||||
private void cascadeOnLock(LockEvent event, EntityPersister persister, Object entity) {
|
||||
EventSource source = event.getSession();
|
||||
final EventSource source = event.getSession();
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
persistenceContext.incrementCascadeLevel();
|
||||
try {
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.hibernate.engine.spi.EntityKey;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.event.spi.EntityCopyObserver;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
|
@ -50,6 +49,7 @@ import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTra
|
|||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTracker;
|
||||
import static org.hibernate.event.internal.EntityState.getEntityState;
|
||||
|
||||
/**
|
||||
* Defines the default copy event listener used by hibernate for copying entities
|
||||
|
@ -147,13 +147,13 @@ public class DefaultMergeEventListener
|
|||
private void merge(MergeEvent event, MergeContext copiedAlready, Object entity) {
|
||||
switch ( entityState( event, entity ) ) {
|
||||
case DETACHED:
|
||||
entityIsDetached(event, copiedAlready);
|
||||
entityIsDetached( event, copiedAlready );
|
||||
break;
|
||||
case TRANSIENT:
|
||||
entityIsTransient(event, copiedAlready);
|
||||
entityIsTransient( event, copiedAlready );
|
||||
break;
|
||||
case PERSISTENT:
|
||||
entityIsPersistent(event, copiedAlready);
|
||||
entityIsPersistent( event, copiedAlready );
|
||||
break;
|
||||
default: //DELETED
|
||||
throw new ObjectDeletedException(
|
||||
|
@ -186,7 +186,7 @@ public class DefaultMergeEventListener
|
|||
}
|
||||
}
|
||||
}
|
||||
return EntityState.getEntityState( entity, event.getEntityName(), entry, source, false );
|
||||
return getEntityState( entity, event.getEntityName(), entry, source, false );
|
||||
}
|
||||
|
||||
protected void entityIsPersistent(MergeEvent event, MergeContext copyCache) {
|
||||
|
@ -343,7 +343,6 @@ public class DefaultMergeEventListener
|
|||
markInterceptorDirty( entity, target );
|
||||
event.setResult( result );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Object targetEntity(MergeEvent event, Object entity, EntityPersister persister, Object id, Object result) {
|
||||
|
@ -380,7 +379,7 @@ public class DefaultMergeEventListener
|
|||
}
|
||||
else {
|
||||
// check that entity id = requestedId
|
||||
Object entityId = persister.getIdentifier( entity, source );
|
||||
final Object entityId = persister.getIdentifier( entity, source );
|
||||
if ( !persister.getIdentifierType().isEqual( id, entityId, source.getFactory() ) ) {
|
||||
throw new HibernateException( "merge requested with id not matching id of passed entity" );
|
||||
}
|
||||
|
@ -400,8 +399,10 @@ public class DefaultMergeEventListener
|
|||
if ( isPersistentAttributeInterceptable( incoming )
|
||||
&& persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
|
||||
|
||||
final PersistentAttributeInterceptor incomingInterceptor = asPersistentAttributeInterceptable( incoming ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor managedInterceptor = asPersistentAttributeInterceptable( managed ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor incomingInterceptor =
|
||||
asPersistentAttributeInterceptable( incoming ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor managedInterceptor =
|
||||
asPersistentAttributeInterceptable( managed ).$$_hibernate_getInterceptor();
|
||||
|
||||
// todo - do we need to specially handle the case where both `incoming` and `managed` are initialized, but
|
||||
// with different attributes initialized?
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.event.spi.PersistContext;
|
|||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DefaultPersistOnFlushEventListener extends DefaultPersistEventListener {
|
||||
@Override
|
||||
protected CascadingAction<PersistContext> getCascadeAction() {
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* We do 2 things here:<ul>
|
||||
* We do two things here:
|
||||
* <ul>
|
||||
* <li>Call {@link Lifecycle} interface if necessary</li>
|
||||
* <li>Perform needed {@link EntityEntry#getLockMode()} related processing</li>
|
||||
* </ul>
|
||||
|
@ -49,34 +50,26 @@ public class DefaultPostLoadEventListener implements PostLoadEventListener, Call
|
|||
throw new AssertionFailure( "possible non-threadsafe access to the session" );
|
||||
}
|
||||
|
||||
final LockMode lockMode = entry.getLockMode();
|
||||
switch (lockMode) {
|
||||
switch ( entry.getLockMode() ) {
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
final Object nextVersion = persister.forceVersionIncrement(
|
||||
entry.getId(),
|
||||
entry.getVersion(),
|
||||
session
|
||||
);
|
||||
entry.forceLocked(entity, nextVersion);
|
||||
final Object nextVersion = entry.getPersister()
|
||||
.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
|
||||
entry.forceLocked( entity, nextVersion );
|
||||
break;
|
||||
case OPTIMISTIC_FORCE_INCREMENT:
|
||||
final EntityIncrementVersionProcess incrementVersion = new EntityIncrementVersionProcess(entity);
|
||||
session.getActionQueue().registerProcess(incrementVersion);
|
||||
session.getActionQueue().registerProcess( new EntityIncrementVersionProcess( entity ) );
|
||||
break;
|
||||
case OPTIMISTIC:
|
||||
final EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess(entity);
|
||||
session.getActionQueue().registerProcess(verifyVersion);
|
||||
session.getActionQueue().registerProcess( new EntityVerifyVersionProcess( entity ) );
|
||||
break;
|
||||
}
|
||||
|
||||
invokeLoadLifecycle(event, session);
|
||||
invokeLoadLifecycle( event, session );
|
||||
|
||||
}
|
||||
|
||||
protected void invokeLoadLifecycle(PostLoadEvent event, EventSource session) {
|
||||
if ( event.getPersister().implementsLifecycle() ) {
|
||||
//log.debug( "calling onLoad()" );
|
||||
( (Lifecycle) event.getEntity() ).onLoad( session, event.getId() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.hibernate.type.CollectionType;
|
|||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||
|
||||
/**
|
||||
* Defines the default refresh event listener used by hibernate for refreshing entities
|
||||
* in response to generated refresh events.
|
||||
|
@ -89,19 +91,18 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
final Object id;
|
||||
if ( entry == null ) {
|
||||
//refresh() does not pass an entityName
|
||||
persister = source.getEntityPersister( event.getEntityName(), object);
|
||||
id = persister.getIdentifier(object, event.getSession() );
|
||||
persister = source.getEntityPersister( event.getEntityName(), object );
|
||||
id = persister.getIdentifier( object, event.getSession() );
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Refreshing transient {0}",
|
||||
MessageHelper.infoString( persister, id, source.getFactory() )
|
||||
infoString( persister, id, source.getFactory() )
|
||||
);
|
||||
}
|
||||
final EntityKey key = source.generateEntityKey( id, persister );
|
||||
if ( persistenceContext.getEntry( key ) != null ) {
|
||||
if ( persistenceContext.getEntry( source.generateEntityKey( id, persister ) ) != null ) {
|
||||
throw new PersistentObjectException(
|
||||
"attempted to refresh transient instance when persistent instance was already associated with the Session: " +
|
||||
MessageHelper.infoString( persister, id, source.getFactory() )
|
||||
"attempted to refresh transient instance when persistent instance was already associated with the Session: "
|
||||
+ infoString( persister, id, source.getFactory() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +110,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Refreshing ",
|
||||
MessageHelper.infoString( entry.getPersister(), entry.getId(), source.getFactory() )
|
||||
infoString( entry.getPersister(), entry.getId(), source.getFactory() )
|
||||
);
|
||||
}
|
||||
if ( !entry.isExistsInDatabase() ) {
|
||||
|
@ -140,12 +141,12 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
evictEntity( object, persister, id, source);
|
||||
evictCachedCollections( persister, id, source);
|
||||
evictEntity( object, persister, id, source );
|
||||
evictCachedCollections( persister, id, source );
|
||||
|
||||
final Object result = source.getLoadQueryInfluencers().fromInternalFetchProfile(
|
||||
CascadingFetchProfile.REFRESH,
|
||||
() -> doRefresh(event, source, object, entry, persister, id, persistenceContext)
|
||||
() -> doRefresh( event, source, object, entry, persister, id, persistenceContext )
|
||||
);
|
||||
UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
|
||||
}
|
||||
|
@ -183,7 +184,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
// Handle the requested lock-mode (if one) in relation to the entry's (if one) current lock-mode
|
||||
LockOptions lockOptionsToUse = event.getLockOptions();
|
||||
final LockMode requestedLockMode = lockOptionsToUse.getLockMode();
|
||||
LockMode postRefreshLockMode = null;
|
||||
final LockMode postRefreshLockMode;
|
||||
if ( entry != null ) {
|
||||
final LockMode currentLockMode = entry.getLockMode();
|
||||
if ( currentLockMode.greaterThan( requestedLockMode ) ) {
|
||||
|
@ -207,8 +208,15 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
}
|
||||
else {
|
||||
lockOptionsToUse.setLockMode( currentLockMode );
|
||||
postRefreshLockMode = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
postRefreshLockMode = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
postRefreshLockMode = null;
|
||||
}
|
||||
|
||||
final Object result = persister.load( id, object, lockOptionsToUse, source );
|
||||
|
@ -245,7 +253,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
for ( Type type : types ) {
|
||||
if ( type.isCollectionType() ) {
|
||||
final String role = ((CollectionType) type).getRole();
|
||||
CollectionPersister collectionPersister = metamodel.getCollectionDescriptor( role );
|
||||
final CollectionPersister collectionPersister = metamodel.getCollectionDescriptor( role );
|
||||
if ( collectionPersister.hasCache() ) {
|
||||
final CollectionDataAccess cache = collectionPersister.getCacheAccessStrategy();
|
||||
final Object ck = cache.generateCacheKey(
|
||||
|
@ -260,7 +268,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
}
|
||||
}
|
||||
else if ( type.isComponentType() ) {
|
||||
CompositeType compositeType = (CompositeType) type;
|
||||
final CompositeType compositeType = (CompositeType) type;
|
||||
evictCachedCollections( compositeType.getSubtypes(), id, source );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.event.internal;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.NaturalIdResolutions;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.ResolveNaturalIdEvent;
|
||||
import org.hibernate.event.spi.ResolveNaturalIdEventListener;
|
||||
|
@ -18,6 +19,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
|
|||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||
|
||||
/**
|
||||
* Defines the default load event listeners used by hibernate for loading entities
|
||||
|
@ -53,17 +55,17 @@ public class DefaultResolveNaturalIdEventListener
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Attempting to resolve: {0}#{1}",
|
||||
MessageHelper.infoString( persister ),
|
||||
infoString( persister ),
|
||||
event.getNaturalIdValues()
|
||||
);
|
||||
}
|
||||
|
||||
Object entityId = resolveFromCache( event );
|
||||
final Object entityId = resolveFromCache( event );
|
||||
if ( entityId != null ) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Resolved object in cache: {0}#{1}",
|
||||
MessageHelper.infoString( persister ),
|
||||
infoString( persister ),
|
||||
event.getNaturalIdValues()
|
||||
);
|
||||
}
|
||||
|
@ -73,7 +75,7 @@ public class DefaultResolveNaturalIdEventListener
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Object not resolved in any cache: {0}#{1}",
|
||||
MessageHelper.infoString( persister ),
|
||||
infoString( persister ),
|
||||
event.getNaturalIdValues()
|
||||
);
|
||||
}
|
||||
|
@ -88,9 +90,8 @@ public class DefaultResolveNaturalIdEventListener
|
|||
*
|
||||
* @return The entity from the cache, or null.
|
||||
*/
|
||||
protected Object resolveFromCache(final ResolveNaturalIdEvent event) {
|
||||
return event.getSession().getPersistenceContextInternal()
|
||||
.getNaturalIdResolutions()
|
||||
protected Object resolveFromCache(ResolveNaturalIdEvent event) {
|
||||
return getNaturalIdResolutions( event)
|
||||
.findCachedIdByNaturalId( event.getOrderedNaturalIdValues(), event.getEntityPersister() );
|
||||
}
|
||||
|
||||
|
@ -102,16 +103,14 @@ public class DefaultResolveNaturalIdEventListener
|
|||
*
|
||||
* @return The object loaded from the datasource, or null if not found.
|
||||
*/
|
||||
protected Object loadFromDatasource(final ResolveNaturalIdEvent event) {
|
||||
protected Object loadFromDatasource(ResolveNaturalIdEvent event) {
|
||||
final EventSource session = event.getSession();
|
||||
final EntityPersister entityPersister = event.getEntityPersister();
|
||||
final StatisticsImplementor statistics = session.getFactory().getStatistics();
|
||||
final boolean statisticsEnabled = statistics.isStatisticsEnabled();
|
||||
long startTime = 0;
|
||||
if ( statisticsEnabled ) {
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
final long startTime = statisticsEnabled ? System.nanoTime() : 0;
|
||||
|
||||
final Object pk = event.getEntityPersister().loadEntityIdByNaturalId(
|
||||
final Object pk = entityPersister.loadEntityIdByNaturalId(
|
||||
event.getOrderedNaturalIdValues(),
|
||||
event.getLockOptions(),
|
||||
session
|
||||
|
@ -120,15 +119,18 @@ public class DefaultResolveNaturalIdEventListener
|
|||
if ( statisticsEnabled ) {
|
||||
final long endTime = System.nanoTime();
|
||||
final long milliseconds = MILLISECONDS.convert( endTime - startTime, NANOSECONDS );
|
||||
statistics.naturalIdQueryExecuted( event.getEntityPersister().getRootEntityName(), milliseconds );
|
||||
statistics.naturalIdQueryExecuted( entityPersister.getRootEntityName(), milliseconds );
|
||||
}
|
||||
|
||||
//PK can be null if the entity doesn't exist
|
||||
if ( pk != null ) {
|
||||
session.getPersistenceContextInternal()
|
||||
.getNaturalIdResolutions()
|
||||
.cacheResolutionFromLoad( pk, event.getOrderedNaturalIdValues(), event.getEntityPersister() );
|
||||
getNaturalIdResolutions( event )
|
||||
.cacheResolutionFromLoad( pk, event.getOrderedNaturalIdValues(), entityPersister );
|
||||
}
|
||||
return pk;
|
||||
}
|
||||
|
||||
private static NaturalIdResolutions getNaturalIdResolutions(ResolveNaturalIdEvent event) {
|
||||
return event.getSession().getPersistenceContextInternal().getNaturalIdResolutions();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
public class LoaderHelper {
|
||||
|
||||
public static void upgradeLock(Object object, EntityEntry entry, LockOptions lockOptions, EventSource session) {
|
||||
LockMode requestedLockMode = lockOptions.getLockMode();
|
||||
final LockMode requestedLockMode = lockOptions.getLockMode();
|
||||
if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
|
||||
// The user requested a "greater" (i.e. more restrictive) form of
|
||||
// pessimistic lock
|
||||
|
|
Loading…
Reference in New Issue