minor stylistic review and generics fixes in event stuff
This commit is contained in:
parent
c086fff1f8
commit
d86e9b6ab6
|
@ -551,7 +551,7 @@ public class ActionQueue {
|
|||
*
|
||||
* @return {@code true} if we contain pending actions against any of the given tables; {@code false} otherwise.
|
||||
*/
|
||||
public boolean areTablesToBeUpdated(Set<Serializable> tables) {
|
||||
public boolean areTablesToBeUpdated(Set<? extends Serializable> tables) {
|
||||
if ( tables.isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ public class ActionQueue {
|
|||
return areTablesToBeUpdated( unresolvedInsertions, tables );
|
||||
}
|
||||
|
||||
private static boolean areTablesToBeUpdated(ExecutableList<?> actions, Set<Serializable> tableSpaces) {
|
||||
private static boolean areTablesToBeUpdated(ExecutableList<?> actions, Set<? extends Serializable> tableSpaces) {
|
||||
if ( actions == null || actions.isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ public class ActionQueue {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static boolean areTablesToBeUpdated(UnresolvedEntityInsertActions actions, Set<Serializable> tableSpaces) {
|
||||
private static boolean areTablesToBeUpdated(UnresolvedEntityInsertActions actions, Set<? extends Serializable> tableSpaces) {
|
||||
for ( Executable action : actions.getDependentEntityInsertActions() ) {
|
||||
final Serializable[] spaces = action.getPropertySpaces();
|
||||
for ( Serializable space : spaces ) {
|
||||
|
|
|
@ -28,10 +28,8 @@ import org.hibernate.engine.spi.PersistenceContext;
|
|||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.event.service.spi.EventListenerGroup;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.service.spi.JpaBootstrapSensitive;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.event.spi.FlushEntityEvent;
|
||||
import org.hibernate.event.spi.FlushEntityEventListener;
|
||||
import org.hibernate.event.spi.FlushEvent;
|
||||
|
@ -103,7 +101,6 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
logFlushResults( event );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void logFlushResults(FlushEvent event) {
|
||||
if ( !LOG.isDebugEnabled() ) {
|
||||
return;
|
||||
|
@ -151,7 +148,7 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
}
|
||||
|
||||
private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, Object anything)
|
||||
throws HibernateException {
|
||||
throws HibernateException {
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
persistenceContext.incrementCascadeLevel();
|
||||
try {
|
||||
|
@ -163,21 +160,11 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
}
|
||||
|
||||
protected Object getAnything() {
|
||||
if ( jpaBootstrap ) {
|
||||
return new IdentityHashMap( 10 );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
return jpaBootstrap ? new IdentityHashMap<>(10) : null;
|
||||
}
|
||||
|
||||
protected CascadingAction getCascadingAction() {
|
||||
if ( jpaBootstrap ) {
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
else {
|
||||
return CascadingActions.SAVE_UPDATE;
|
||||
}
|
||||
return jpaBootstrap ? CascadingActions.PERSIST_ON_FLUSH : CascadingActions.SAVE_UPDATE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,7 +187,8 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
* 2. schedule any entity updates
|
||||
* 3. search out any reachable collections
|
||||
*/
|
||||
private int flushEntities(final FlushEvent event, final PersistenceContext persistenceContext) throws HibernateException {
|
||||
private int flushEntities(final FlushEvent event, final PersistenceContext persistenceContext)
|
||||
throws HibernateException {
|
||||
|
||||
LOG.trace( "Flushing entities and processing referenced collections" );
|
||||
|
||||
|
@ -238,8 +226,8 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
* process any unreferenced collections and then inspect all known collections,
|
||||
* scheduling creates/removes/updates
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private int flushCollections(final EventSource session, final PersistenceContext persistenceContext) throws HibernateException {
|
||||
private int flushCollections(final EventSource session, final PersistenceContext persistenceContext)
|
||||
throws HibernateException {
|
||||
LOG.trace( "Processing unreferenced collections" );
|
||||
|
||||
final int count = persistenceContext.getCollectionEntriesSize();
|
||||
|
|
|
@ -33,6 +33,6 @@ public abstract class AbstractLockUpgradeEventListener extends AbstractReassocia
|
|||
* @param source The session which is the source of the event being processed.
|
||||
*/
|
||||
protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOptions, EventSource source) {
|
||||
LoaderHelper.upgradeLock( object, entry, lockOptions, (SessionImplementor) source );
|
||||
LoaderHelper.upgradeLock( object, entry, lockOptions, source );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public abstract class AbstractReassociateEventListener {
|
|||
|
||||
EntityEntry newEntry = persistenceContext.addEntity(
|
||||
object,
|
||||
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
|
||||
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
|
||||
values,
|
||||
key,
|
||||
version,
|
||||
|
|
|
@ -330,18 +330,22 @@ public abstract class AbstractSaveEventListener
|
|||
boolean shouldDelayIdentityInserts) {
|
||||
if ( useIdentityColumn ) {
|
||||
EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
|
||||
values, entity, persister, isVersionIncrementDisabled(), source, shouldDelayIdentityInserts
|
||||
values,
|
||||
entity,
|
||||
persister,
|
||||
isVersionIncrementDisabled(),
|
||||
source,
|
||||
shouldDelayIdentityInserts
|
||||
);
|
||||
source.getActionQueue().addAction( insert );
|
||||
return insert;
|
||||
}
|
||||
else {
|
||||
final Object version = Versioning.getVersion( values, persister );
|
||||
final EntityInsertAction insert = new EntityInsertAction(
|
||||
id,
|
||||
values,
|
||||
entity,
|
||||
version,
|
||||
Versioning.getVersion( values, persister ),
|
||||
persister,
|
||||
isVersionIncrementDisabled(),
|
||||
source
|
||||
|
|
|
@ -79,7 +79,7 @@ public class DefaultAutoFlushEventListener extends AbstractFlushingEventListener
|
|||
|
||||
private boolean flushIsReallyNeeded(AutoFlushEvent event, final EventSource source) {
|
||||
return source.getHibernateFlushMode() == FlushMode.ALWAYS
|
||||
|| source.getActionQueue().areTablesToBeUpdated( event.getQuerySpaces() );
|
||||
|| source.getActionQueue().areTablesToBeUpdated( event.getQuerySpaces() );
|
||||
}
|
||||
|
||||
private boolean flushMightBeNeeded(final EventSource source) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.engine.internal.Cascade;
|
|||
import org.hibernate.engine.internal.CascadePoint;
|
||||
import org.hibernate.engine.internal.ForeignKeys;
|
||||
import org.hibernate.engine.internal.Nullability;
|
||||
import org.hibernate.engine.internal.Nullability.NullabilityCheckType;
|
||||
import org.hibernate.engine.spi.CascadingActions;
|
||||
import org.hibernate.engine.spi.EntityEntry;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
|
@ -184,7 +185,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
EntityPersister persister = source.getEntityPersister( entityName, event.getObject() );
|
||||
Object id = persister.getIdentifier( event.getObject(), source );
|
||||
entityName = entityName == null ? source.guessEntityName( event.getObject() ) : entityName;
|
||||
throw new IllegalArgumentException("Removing a detached instance "+ entityName + "#" + id);
|
||||
throw new IllegalArgumentException( "Removing a detached instance " + entityName + "#" + id );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,17 +248,11 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
}
|
||||
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
final Type[] propTypes = persister.getPropertyTypes();
|
||||
final Object version = entityEntry.getVersion();
|
||||
|
||||
final Object[] currentState;
|
||||
if ( entityEntry.getLoadedState() == null ) {
|
||||
//ie. the entity came in from update()
|
||||
currentState = persister.getPropertyValues( entity );
|
||||
}
|
||||
else {
|
||||
currentState = entityEntry.getLoadedState();
|
||||
}
|
||||
final Object[] currentState = entityEntry.getLoadedState() == null
|
||||
? persister.getPropertyValues(entity) //i.e. the entity came in from update()
|
||||
: entityEntry.getLoadedState();
|
||||
|
||||
final Object[] deletedState = createDeletedState( persister, currentState, session );
|
||||
entityEntry.setDeletedState( deletedState );
|
||||
|
@ -267,17 +262,19 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
entityEntry.getId(),
|
||||
deletedState,
|
||||
persister.getPropertyNames(),
|
||||
propTypes
|
||||
persister.getPropertyTypes()
|
||||
);
|
||||
|
||||
// before any callbacks, etc, so subdeletions see that this deletion happened first
|
||||
// before any callbacks, etc., so subdeletions see that this deletion happened first
|
||||
persistenceContext.setEntryStatus( entityEntry, Status.DELETED );
|
||||
final EntityKey key = session.generateEntityKey( entityEntry.getId(), persister );
|
||||
|
||||
cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities );
|
||||
|
||||
new ForeignKeys.Nullifier( entity, true, false, session, persister ).nullifyTransientReferences( entityEntry.getDeletedState() );
|
||||
new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, Nullability.NullabilityCheckType.DELETE );
|
||||
new ForeignKeys.Nullifier( entity, true, false, session, persister )
|
||||
.nullifyTransientReferences( entityEntry.getDeletedState() );
|
||||
new Nullability( session )
|
||||
.checkNullability( entityEntry.getDeletedState(), persister, NullabilityCheckType.DELETE );
|
||||
persistenceContext.registerNullifiableEntityKey( key );
|
||||
|
||||
if ( isOrphanRemovalBeforeUpdates ) {
|
||||
|
|
|
@ -36,8 +36,6 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.metamodel.RuntimeMetamodels;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
|
@ -95,7 +93,8 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
Object[] loaded,
|
||||
SessionImplementor session) {
|
||||
if ( entity instanceof PersistentAttributeInterceptable ) {
|
||||
final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor interceptor =
|
||||
( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||
// EARLY EXIT!!!
|
||||
// nothing to check - the entity is an un-initialized enhancement-as-proxy reference
|
||||
|
@ -104,16 +103,9 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
|
||||
final NaturalIdMapping naturalIdMapping = persister.getNaturalIdMapping();
|
||||
if ( naturalIdMapping == null ) {
|
||||
return;
|
||||
if ( naturalIdMapping != null && entry.getStatus() != Status.READ_ONLY ) {
|
||||
naturalIdMapping.verifyFlushState( entry.getId(), current, loaded, session );
|
||||
}
|
||||
|
||||
if ( entry.getStatus() == Status.READ_ONLY ) {
|
||||
// nothing to check
|
||||
return;
|
||||
}
|
||||
|
||||
naturalIdMapping.verifyFlushState( entry.getId(), current, loaded, session );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,7 +135,8 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
|
||||
if ( status != Status.DELETED ) {
|
||||
// now update the object .. has to be outside the main if block above (because of collections)
|
||||
// now update the object
|
||||
// has to be outside the main if block above (because of collections)
|
||||
if ( substitute ) {
|
||||
persister.setPropertyValues( entity, values );
|
||||
}
|
||||
|
@ -159,26 +152,26 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
|
||||
private Object[] getValues(Object entity, EntityEntry entry, boolean mightBeDirty, SessionImplementor session) {
|
||||
final Object[] loadedState = entry.getLoadedState();
|
||||
final Status status = entry.getStatus();
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
|
||||
final Object[] values;
|
||||
if ( status == Status.DELETED ) {
|
||||
if ( entry.getStatus() == Status.DELETED ) {
|
||||
//grab its state saved at deletion
|
||||
values = entry.getDeletedState();
|
||||
return entry.getDeletedState();
|
||||
}
|
||||
else if ( !mightBeDirty && loadedState != null ) {
|
||||
values = loadedState;
|
||||
return loadedState;
|
||||
}
|
||||
else {
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
|
||||
checkId( entity, persister, entry.getId(), session );
|
||||
|
||||
// grab its current state
|
||||
values = persister.getPropertyValues( entity );
|
||||
Object[] values = persister.getPropertyValues( entity );
|
||||
|
||||
checkNaturalId( persister, entity, entry, values, loadedState, session );
|
||||
|
||||
return values;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private boolean wrapCollections(
|
||||
|
@ -210,26 +203,26 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
|
||||
private boolean isUpdateNecessary(final FlushEntityEvent event, final boolean mightBeDirty) {
|
||||
final Status status = event.getEntityEntry().getStatus();
|
||||
if ( mightBeDirty || status == Status.DELETED ) {
|
||||
EntityEntry entry = event.getEntityEntry();
|
||||
if ( mightBeDirty || entry.getStatus() == Status.DELETED ) {
|
||||
// compare to cached state (ignoring collections unless versioned)
|
||||
dirtyCheck( event );
|
||||
if ( isUpdateNecessary( event ) ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ( SelfDirtinessTracker.class.isInstance( event.getEntity() ) ) {
|
||||
if ( event.getEntity() instanceof SelfDirtinessTracker ) {
|
||||
( (SelfDirtinessTracker) event.getEntity() ).$$_hibernate_clearDirtyAttributes();
|
||||
}
|
||||
event.getSession()
|
||||
.getFactory()
|
||||
EventSource source = event.getSession();
|
||||
source.getFactory()
|
||||
.getCustomEntityDirtinessStrategy()
|
||||
.resetDirty( event.getEntity(), event.getEntityEntry().getPersister(), event.getSession() );
|
||||
.resetDirty( event.getEntity(), entry.getPersister(), source );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return hasDirtyCollections( event, event.getEntityEntry().getPersister(), status );
|
||||
return hasDirtyCollections( event );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,34 +234,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
final EntityPersister persister = entry.getPersister();
|
||||
final Object[] values = event.getPropertyValues();
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( status == Status.DELETED ) {
|
||||
if ( !persister.isMutable() ) {
|
||||
LOG.tracev(
|
||||
"Updating immutable, deleted entity: {0}",
|
||||
MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
else if ( !entry.isModifiableEntity() ) {
|
||||
LOG.tracev(
|
||||
"Updating non-modifiable, deleted entity: {0}",
|
||||
MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
else {
|
||||
LOG.tracev(
|
||||
"Updating deleted entity: {0}",
|
||||
MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.tracev(
|
||||
"Updating entity: {0}",
|
||||
MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
}
|
||||
logScheduleUpdate( entry, session, status, persister );
|
||||
|
||||
final boolean intercepted = !entry.isBeingReplicated() && handleInterception( event );
|
||||
|
||||
|
@ -296,9 +262,9 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
values,
|
||||
dirtyProperties,
|
||||
event.hasDirtyCollection(),
|
||||
( status == Status.DELETED && !entry.isModifiableEntity() ?
|
||||
status == Status.DELETED && !entry.isModifiableEntity() ?
|
||||
persister.getPropertyValues( entity ) :
|
||||
entry.getLoadedState() ),
|
||||
entry.getLoadedState(),
|
||||
entry.getVersion(),
|
||||
nextVersion,
|
||||
entity,
|
||||
|
@ -311,15 +277,47 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
return intercepted;
|
||||
}
|
||||
|
||||
private static void logScheduleUpdate(EntityEntry entry, EventSource session, Status status, EntityPersister persister) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( status == Status.DELETED ) {
|
||||
if ( !persister.isMutable() ) {
|
||||
LOG.tracev(
|
||||
"Updating immutable, deleted entity: {0}",
|
||||
MessageHelper.infoString(persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
else if ( !entry.isModifiableEntity() ) {
|
||||
LOG.tracev(
|
||||
"Updating non-modifiable, deleted entity: {0}",
|
||||
MessageHelper.infoString(persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
else {
|
||||
LOG.tracev(
|
||||
"Updating deleted entity: {0}",
|
||||
MessageHelper.infoString(persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.tracev(
|
||||
"Updating entity: {0}",
|
||||
MessageHelper.infoString(persister, entry.getId(), session.getFactory() )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean handleInterception(FlushEntityEvent event) {
|
||||
SessionImplementor session = event.getSession();
|
||||
EntityEntry entry = event.getEntityEntry();
|
||||
EntityPersister persister = entry.getPersister();
|
||||
Object entity = event.getEntity();
|
||||
|
||||
//give the Interceptor a chance to modify property values
|
||||
final Object[] values = event.getPropertyValues();
|
||||
final boolean intercepted = invokeInterceptor( session, entity, entry, values, persister );
|
||||
final boolean intercepted = invokeInterceptor(
|
||||
event.getSession(),
|
||||
event.getEntity(),
|
||||
event.getEntityEntry(),
|
||||
event.getPropertyValues(),
|
||||
event.getEntityEntry().getPersister()
|
||||
);
|
||||
|
||||
//now we might need to recalculate the dirtyProperties array
|
||||
if ( intercepted && event.isDirtyCheckPossible() ) {
|
||||
|
@ -335,6 +333,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
EntityEntry entry,
|
||||
final Object[] values,
|
||||
EntityPersister persister) {
|
||||
|
||||
boolean isDirty = false;
|
||||
if ( entry.getStatus() != Status.DELETED ) {
|
||||
if ( callbackRegistry.preUpdate( entity ) ) {
|
||||
|
@ -356,14 +355,14 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
|
||||
private boolean copyState(Object entity, Type[] types, Object[] state, SessionFactory sf) {
|
||||
// copy the entity state into the state array and return true if the state has changed
|
||||
final SessionFactoryImplementor sessionFactory = sf.unwrap( SessionFactoryImplementor.class );
|
||||
final RuntimeMetamodels runtimeMetamodels = sessionFactory.getRuntimeMetamodels();
|
||||
final EntityMappingType entityMappingType = runtimeMetamodels.getEntityMappingType( entity.getClass() );
|
||||
final Object[] newState = entityMappingType.getEntityPersister().getValues( entity );
|
||||
final Object[] newState = sf.unwrap( SessionFactoryImplementor.class )
|
||||
.getRuntimeMetamodels()
|
||||
.getEntityMappingType( entity.getClass() )
|
||||
.getEntityPersister()
|
||||
.getValues( entity );
|
||||
|
||||
int size = newState.length;
|
||||
boolean isDirty = false;
|
||||
for ( int index = 0; index < size; index++ ) {
|
||||
for ( int index = 0, size = newState.length; index < size; index++ ) {
|
||||
if ( ( state[index] == LazyPropertyInitializer.UNFETCHED_PROPERTY &&
|
||||
newState[index] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) ||
|
||||
( state[index] != newState[index] && !types[index].isEqual( state[index], newState[index] ) ) ) {
|
||||
|
@ -389,18 +388,17 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
return Versioning.getVersion( values, persister );
|
||||
}
|
||||
else {
|
||||
int[] dirtyProperties = event.getDirtyProperties();
|
||||
|
||||
final boolean isVersionIncrementRequired = isVersionIncrementRequired(
|
||||
event,
|
||||
entry,
|
||||
persister,
|
||||
dirtyProperties
|
||||
event.getDirtyProperties()
|
||||
);
|
||||
|
||||
final Object nextVersion = isVersionIncrementRequired ?
|
||||
Versioning.increment( entry.getVersion(), persister.getVersionJavaType(), event.getSession() ) :
|
||||
entry.getVersion(); //use the current version
|
||||
final Object nextVersion = isVersionIncrementRequired
|
||||
? Versioning.increment( entry.getVersion(), persister.getVersionJavaType(), event.getSession() )
|
||||
: entry.getVersion(); //use the current version
|
||||
|
||||
Versioning.setVersion( values, nextVersion, persister );
|
||||
|
||||
|
@ -419,7 +417,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
EntityPersister persister,
|
||||
int[] dirtyProperties
|
||||
) {
|
||||
final boolean isVersionIncrementRequired = entry.getStatus() != Status.DELETED && (
|
||||
return entry.getStatus() != Status.DELETED && (
|
||||
dirtyProperties == null ||
|
||||
Versioning.isVersionIncrementRequired(
|
||||
dirtyProperties,
|
||||
|
@ -427,7 +425,6 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
persister.getPropertyVersionability()
|
||||
)
|
||||
);
|
||||
return isVersionIncrementRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -436,28 +433,24 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
* Note: this method is quite slow, avoid calling if possible!
|
||||
*/
|
||||
protected final boolean isUpdateNecessary(FlushEntityEvent event) throws HibernateException {
|
||||
|
||||
EntityPersister persister = event.getEntityEntry().getPersister();
|
||||
Status status = event.getEntityEntry().getStatus();
|
||||
|
||||
if ( !event.isDirtyCheckPossible() ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
int[] dirtyProperties = event.getDirtyProperties();
|
||||
if ( dirtyProperties != null && dirtyProperties.length != 0 ) {
|
||||
return true; //TODO: suck into event class
|
||||
}
|
||||
else {
|
||||
return hasDirtyCollections( event, persister, status );
|
||||
return hasDirtyCollections( event );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasDirtyCollections(FlushEntityEvent event, EntityPersister persister, Status status) {
|
||||
if ( isCollectionDirtyCheckNecessary( persister, status ) ) {
|
||||
private boolean hasDirtyCollections(FlushEntityEvent event) {
|
||||
EntityPersister persister = event.getEntityEntry().getPersister();
|
||||
if ( isCollectionDirtyCheckNecessary( persister, event.getEntityEntry().getStatus() ) ) {
|
||||
DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor(
|
||||
event.getEntity(),
|
||||
event.getSession(),
|
||||
|
@ -474,9 +467,9 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
}
|
||||
|
||||
private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) {
|
||||
return ( status == Status.MANAGED || status == Status.READ_ONLY ) &&
|
||||
persister.isVersioned() &&
|
||||
persister.hasCollections();
|
||||
return ( status == Status.MANAGED || status == Status.READ_ONLY )
|
||||
&& persister.isVersioned()
|
||||
&& persister.hasCollections();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -503,11 +496,13 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
|
||||
if ( dirtyProperties == null ) {
|
||||
if ( entity instanceof SelfDirtinessTracker ) {
|
||||
if ( ( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes() || persister.hasMutableProperties() ) {
|
||||
boolean hasDirtyAttributes = ((SelfDirtinessTracker) entity).$$_hibernate_hasDirtyAttributes();
|
||||
if ( hasDirtyAttributes || persister.hasMutableProperties() ) {
|
||||
String[] dirtyAttributes = ((SelfDirtinessTracker) entity).$$_hibernate_getDirtyAttributes();
|
||||
dirtyProperties = persister.resolveDirtyAttributeIndexes(
|
||||
values,
|
||||
loadedState,
|
||||
( (SelfDirtinessTracker) entity ).$$_hibernate_getDirtyAttributes(),
|
||||
dirtyAttributes,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
@ -557,7 +552,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
// dirty check against the usual snapshot of the entity
|
||||
dirtyProperties = persister.findDirty( values, loadedState, entity, session );
|
||||
}
|
||||
else if ( entry.getStatus() == Status.DELETED && !event.getEntityEntry().isModifiableEntity() ) {
|
||||
else if ( entry.getStatus() == Status.DELETED && !entry.isModifiableEntity() ) {
|
||||
// A non-modifiable (e.g., read-only or immutable) entity needs to be have
|
||||
// references to transient entities set to null before being deleted. No other
|
||||
// fields should be updated.
|
||||
|
|
|
@ -159,10 +159,8 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
|||
return false;
|
||||
}
|
||||
|
||||
CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure().destructure(
|
||||
ce,
|
||||
factory
|
||||
);
|
||||
CollectionCacheEntry cacheEntry = (CollectionCacheEntry)
|
||||
persister.getCacheEntryStructure().destructure( ce, factory );
|
||||
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
cacheEntry.assemble( collection, persister, persistenceContext.getCollectionOwner( id, persister ) );
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.hibernate.proxy.HibernateProxy;
|
|||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
* Defines the default load event listeners used by hibernate for loading entities
|
||||
|
@ -66,7 +65,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() );
|
||||
}
|
||||
|
||||
final Class idClass = persister.getIdentifierType().getReturnedClass();
|
||||
final Class<?> idClass = persister.getIdentifierType().getReturnedClass();
|
||||
if ( idClass != null &&
|
||||
!idClass.isInstance( event.getEntityId() ) &&
|
||||
!(event.getEntityId() instanceof DelayedPostInsertIdentifier) ) {
|
||||
|
@ -128,7 +127,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
final EntityPersister persister,
|
||||
final LoadEvent event,
|
||||
final LoadType loadType,
|
||||
final Class idClass) {
|
||||
final Class<?> idClass) {
|
||||
// we may have the jpa requirement of allowing find-by-id where id is the "simple pk value" of a
|
||||
// dependent objects parent. This is part of its generally goofy derived identity "feature"
|
||||
final EntityIdentifierMapping idMapping = persister.getIdentifierMapping();
|
||||
|
@ -140,15 +139,10 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( singleIdAttribute.getMappedType() instanceof EntityMappingType ) {
|
||||
final EntityMappingType parentIdTargetMapping = (EntityMappingType) singleIdAttribute.getMappedType();
|
||||
final EntityIdentifierMapping parentIdTargetIdMapping = parentIdTargetMapping.getIdentifierMapping();
|
||||
final MappingType mappedType;
|
||||
if ( parentIdTargetIdMapping instanceof CompositeIdentifierMapping ) {
|
||||
mappedType = ( (CompositeIdentifierMapping) parentIdTargetIdMapping ).getMappedIdEmbeddableTypeDescriptor();
|
||||
}
|
||||
else {
|
||||
mappedType = parentIdTargetIdMapping.getMappedType();
|
||||
}
|
||||
final JavaType<?> parentIdJtd = mappedType.getMappedJavaType();
|
||||
if ( parentIdJtd.getJavaTypeClass().isInstance( event.getEntityId() ) ) {
|
||||
final MappingType parentIdType = parentIdTargetIdMapping instanceof CompositeIdentifierMapping
|
||||
? ((CompositeIdentifierMapping) parentIdTargetIdMapping).getMappedIdEmbeddableTypeDescriptor()
|
||||
: parentIdTargetIdMapping.getMappedType();
|
||||
if ( parentIdType.getMappedJavaType().getJavaTypeClass().isInstance( event.getEntityId() ) ) {
|
||||
// yep that's what we have...
|
||||
loadByDerivedIdentitySimplePkValue(
|
||||
event,
|
||||
|
@ -164,7 +158,8 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
}
|
||||
|
||||
throw new TypeMismatchException(
|
||||
"Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass
|
||||
"Provided id of the wrong type for class " + persister.getEntityName()
|
||||
+ ". Expected: " + idClass
|
||||
+ ", got " + event.getEntityId().getClass()
|
||||
);
|
||||
}
|
||||
|
@ -180,10 +175,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
final Object parent = doLoad( event, parentPersister, parentEntityKey, options );
|
||||
|
||||
final Object dependent = dependentIdType.instantiate();
|
||||
dependentIdType.getPartMappingType().setValues(
|
||||
dependent,
|
||||
new Object[] { parent }
|
||||
);
|
||||
dependentIdType.getPartMappingType().setValues( dependent, new Object[] { parent } );
|
||||
final EntityKey dependentEntityKey = session.generateEntityKey( dependent, dependentPersister );
|
||||
event.setEntityId( dependent );
|
||||
|
||||
|
@ -226,8 +218,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
boolean isOptionalInstance = event.getInstanceToLoad() != null;
|
||||
|
||||
if ( entity == null && ( !options.isAllowNulls() || isOptionalInstance ) ) {
|
||||
session
|
||||
.getFactory()
|
||||
session.getFactory()
|
||||
.getEntityNotFoundDelegate()
|
||||
.handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
|
||||
}
|
||||
|
@ -269,7 +260,6 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
|
||||
final EntityMetamodel entityMetamodel = persister.getEntityMetamodel();
|
||||
final boolean entityHasHibernateProxyFactory = persister.getRepresentationStrategy().getProxyFactory() != null;
|
||||
|
||||
// Check for the case where we can use the entity itself as a proxy
|
||||
if ( options.isAllowProxyCreation()
|
||||
|
@ -278,8 +268,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
final Object managed = persistenceContext.getEntity( keyToLoad );
|
||||
if ( managed != null ) {
|
||||
if ( options.isCheckDeleted() ) {
|
||||
final EntityEntry entry = persistenceContext.getEntry( managed );
|
||||
final Status status = entry.getStatus();
|
||||
final Status status = persistenceContext.getEntry( managed ).getStatus();
|
||||
if ( status == Status.DELETED || status == Status.GONE ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -289,7 +278,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
|
||||
// if the entity defines a HibernateProxy factory, see if there is an
|
||||
// existing proxy associated with the PC - and if so, use it
|
||||
if ( entityHasHibernateProxyFactory ) {
|
||||
if ( persister.getRepresentationStrategy().getProxyFactory() != null ) {
|
||||
final Object proxy = persistenceContext.getProxy( keyToLoad );
|
||||
|
||||
if ( proxy != null ) {
|
||||
|
@ -329,7 +318,8 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
|
||||
// This is the crux of HHH-11147
|
||||
// create the (uninitialized) entity instance - has only id set
|
||||
return persister.getBytecodeEnhancementMetadata().createEnhancedProxy( keyToLoad, true, session );
|
||||
return persister.getBytecodeEnhancementMetadata()
|
||||
.createEnhancedProxy( keyToLoad, true, session );
|
||||
}
|
||||
// If we get here, then the entity class has subclasses and there is no HibernateProxy factory.
|
||||
// The entity will get loaded below.
|
||||
|
@ -391,7 +381,6 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
}
|
||||
|
||||
LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
|
||||
|
||||
if ( li.isUnwrap() ) {
|
||||
return li.getImplementation();
|
||||
}
|
||||
|
@ -437,10 +426,9 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
final LoadType options,
|
||||
final PersistenceContext persistenceContext) {
|
||||
Object existing = persistenceContext.getEntity( keyToLoad );
|
||||
final boolean traceEnabled = LOG.isTraceEnabled();
|
||||
if ( existing != null ) {
|
||||
// return existing object or initialized proxy (unless deleted)
|
||||
if ( traceEnabled ) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Entity found in session cache" );
|
||||
}
|
||||
if ( options.isCheckDeleted() ) {
|
||||
|
@ -452,10 +440,12 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
}
|
||||
return existing;
|
||||
}
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Creating new proxy for entity" );
|
||||
else {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Creating new proxy for entity" );
|
||||
}
|
||||
return createProxy( event, persister, keyToLoad, persistenceContext );
|
||||
}
|
||||
return createProxy( event, persister, keyToLoad, persistenceContext );
|
||||
}
|
||||
|
||||
private Object createProxy(
|
||||
|
@ -547,11 +537,8 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
);
|
||||
}
|
||||
|
||||
CacheEntityLoaderHelper.PersistenceContextEntry persistenceContextEntry = CacheEntityLoaderHelper.INSTANCE.loadFromSessionCache(
|
||||
event,
|
||||
keyToLoad,
|
||||
options
|
||||
);
|
||||
CacheEntityLoaderHelper.PersistenceContextEntry persistenceContextEntry
|
||||
= CacheEntityLoaderHelper.INSTANCE.loadFromSessionCache( event, keyToLoad, options );
|
||||
Object entity = persistenceContextEntry.getEntity();
|
||||
|
||||
if ( entity != null ) {
|
||||
|
@ -580,7 +567,9 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( entity != null && persister.hasNaturalIdentifier() ) {
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
persistenceContext.getNaturalIdResolutions().cacheResolutionFromLoad(
|
||||
event.getEntityId(), persister.getNaturalIdMapping().extractNaturalIdFromEntity( entity, session ), persister
|
||||
event.getEntityId(),
|
||||
persister.getNaturalIdMapping().extractNaturalIdFromEntity( entity, session ),
|
||||
persister
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public class DefaultLockEventListener extends AbstractLockUpgradeEventListener i
|
|||
// resulting in two SQL selects
|
||||
|
||||
EntityEntry entry = persistenceContext.getEntry(entity);
|
||||
if (entry==null) {
|
||||
if ( entry == null ) {
|
||||
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
|
||||
final Object id = persister.getIdentifier( entity, source );
|
||||
if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) {
|
||||
|
|
|
@ -76,9 +76,9 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
}
|
||||
|
||||
private EntityCopyObserver createEntityCopyObserver(SessionFactoryImplementor sessionFactory) {
|
||||
final ServiceRegistry serviceRegistry = sessionFactory.getServiceRegistry();
|
||||
final EntityCopyObserverFactory configurationService = serviceRegistry.getService( EntityCopyObserverFactory.class );
|
||||
return configurationService.createEntityCopyObserver();
|
||||
return sessionFactory.getServiceRegistry()
|
||||
.getService( EntityCopyObserverFactory.class )
|
||||
.createEntityCopyObserver();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,7 +127,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
entity = original;
|
||||
}
|
||||
|
||||
if ( copyCache.containsKey( entity ) && ( copyCache.isOperatedOn( entity ) ) ) {
|
||||
if ( copyCache.containsKey( entity ) && copyCache.isOperatedOn( entity ) ) {
|
||||
LOG.trace( "Already in merge process" );
|
||||
event.setResult( entity );
|
||||
}
|
||||
|
@ -364,8 +364,10 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
if ( incoming instanceof PersistentAttributeInterceptable
|
||||
&& persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
|
||||
|
||||
final PersistentAttributeInterceptor incomingInterceptor = ( (PersistentAttributeInterceptable) incoming ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor managedInterceptor = ( (PersistentAttributeInterceptable) managed ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor incomingInterceptor =
|
||||
( (PersistentAttributeInterceptable) incoming ).$$_hibernate_getInterceptor();
|
||||
final PersistentAttributeInterceptor managedInterceptor =
|
||||
( (PersistentAttributeInterceptable) managed ).$$_hibernate_getInterceptor();
|
||||
|
||||
// todo - do we need to specially handle the case where both `incoming` and `managed` are initialized, but
|
||||
// with different attributes initialized?
|
||||
|
|
|
@ -149,7 +149,6 @@ public class DefaultPersistEventListener
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected void entityIsPersistent(PersistEvent event, Map createCache) {
|
||||
LOG.trace( "Ignoring persistent instance" );
|
||||
final EventSource source = event.getSession();
|
||||
|
@ -177,7 +176,6 @@ public class DefaultPersistEventListener
|
|||
* @param event The save event to be handled.
|
||||
* @param createCache The copy cache of entity instance to merge/copy instance.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected void entityIsTransient(PersistEvent event, Map createCache) {
|
||||
LOG.trace( "Saving transient instance" );
|
||||
|
||||
|
@ -189,7 +187,6 @@ public class DefaultPersistEventListener
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private void entityIsDeleted(PersistEvent event, Map createCache) {
|
||||
final EventSource source = event.getSession();
|
||||
|
||||
|
|
|
@ -50,22 +50,24 @@ public class DefaultPostLoadEventListener implements PostLoadEventListener, Call
|
|||
}
|
||||
|
||||
final LockMode lockMode = entry.getLockMode();
|
||||
if ( LockMode.PESSIMISTIC_FORCE_INCREMENT.equals( lockMode ) ) {
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
final Object nextVersion = persister.forceVersionIncrement(
|
||||
entry.getId(),
|
||||
entry.getVersion(),
|
||||
session
|
||||
);
|
||||
entry.forceLocked( entity, nextVersion );
|
||||
}
|
||||
else if ( LockMode.OPTIMISTIC_FORCE_INCREMENT.equals( lockMode ) ) {
|
||||
final EntityIncrementVersionProcess incrementVersion = new EntityIncrementVersionProcess( entity );
|
||||
session.getActionQueue().registerProcess( incrementVersion );
|
||||
}
|
||||
else if ( LockMode.OPTIMISTIC.equals( lockMode ) ) {
|
||||
final EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess( entity );
|
||||
session.getActionQueue().registerProcess( verifyVersion );
|
||||
switch (lockMode) {
|
||||
case PESSIMISTIC_FORCE_INCREMENT:
|
||||
final EntityPersister persister = entry.getPersister();
|
||||
final Object nextVersion = persister.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);
|
||||
break;
|
||||
case OPTIMISTIC:
|
||||
final EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess(entity);
|
||||
session.getActionQueue().registerProcess(verifyVersion);
|
||||
break;
|
||||
}
|
||||
|
||||
invokeLoadLifecycle(event, session);
|
||||
|
|
|
@ -49,7 +49,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultRefreshEventListener.class );
|
||||
|
||||
public void onRefresh(RefreshEvent event) throws HibernateException {
|
||||
onRefresh( event, new IdentityHashMap( 10 ) );
|
||||
onRefresh( event, new IdentityHashMap<>( 10 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,15 +60,12 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
public void onRefresh(RefreshEvent event, Map refreshedAlready) {
|
||||
|
||||
final EventSource source = event.getSession();
|
||||
boolean isTransient;
|
||||
if ( event.getEntityName() != null ) {
|
||||
isTransient = !source.contains( event.getEntityName(), event.getObject() );
|
||||
}
|
||||
else {
|
||||
isTransient = !source.contains( event.getObject() );
|
||||
}
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
|
||||
if ( persistenceContext.reassociateIfUninitializedProxy( event.getObject() ) ) {
|
||||
boolean isTransient = event.getEntityName() != null
|
||||
? !source.contains(event.getEntityName(), event.getObject())
|
||||
: !source.contains(event.getObject());
|
||||
if ( isTransient ) {
|
||||
source.setReadOnly( event.getObject(), source.isDefaultReadOnly() );
|
||||
}
|
||||
|
@ -82,11 +79,11 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
final EntityEntry e = persistenceContext.getEntry( object );
|
||||
final EntityEntry entry = persistenceContext.getEntry( object );
|
||||
final EntityPersister persister;
|
||||
final Object id;
|
||||
|
||||
if ( e == null ) {
|
||||
if ( entry == null ) {
|
||||
//refresh() does not pass an entityName
|
||||
persister = source.getEntityPersister( event.getEntityName(), object );
|
||||
id = persister.getIdentifier( object, event.getSession() );
|
||||
|
@ -111,21 +108,21 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Refreshing ", MessageHelper.infoString(
|
||||
e.getPersister(),
|
||||
e.getId(),
|
||||
entry.getPersister(),
|
||||
entry.getId(),
|
||||
source.getFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
if ( !e.isExistsInDatabase() ) {
|
||||
if ( !entry.isExistsInDatabase() ) {
|
||||
throw new UnresolvableObjectException(
|
||||
e.getId(),
|
||||
entry.getId(),
|
||||
"this instance does not yet exist as a row in the database"
|
||||
);
|
||||
}
|
||||
|
||||
persister = e.getPersister();
|
||||
id = e.getId();
|
||||
persister = entry.getPersister();
|
||||
id = entry.getId();
|
||||
}
|
||||
|
||||
// cascade the refresh prior to refreshing this entity
|
||||
|
@ -139,7 +136,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
refreshedAlready
|
||||
);
|
||||
|
||||
if ( e != null ) {
|
||||
if ( entry != null ) {
|
||||
final EntityKey key = source.generateEntityKey( id, persister );
|
||||
persistenceContext.removeEntity( key );
|
||||
if ( persister.hasCollections() ) {
|
||||
|
@ -171,7 +168,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
|
||||
final Object result = source.getLoadQueryInfluencers().fromInternalFetchProfile(
|
||||
CascadingFetchProfile.REFRESH,
|
||||
() -> doRefresh( event, source, object, e, persister, id, persistenceContext )
|
||||
() -> doRefresh( event, source, object, entry, persister, id, persistenceContext )
|
||||
);
|
||||
|
||||
UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
|
||||
|
@ -200,9 +197,9 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
// the requested lock-mode is less restrictive than the current one
|
||||
// - pass along the current lock-mode (after accounting for WRITE)
|
||||
lockOptionsToUse = LockOptions.copy( event.getLockOptions(), new LockOptions() );
|
||||
if ( currentLockMode == LockMode.WRITE ||
|
||||
currentLockMode == LockMode.PESSIMISTIC_WRITE ||
|
||||
currentLockMode == LockMode.PESSIMISTIC_READ ) {
|
||||
if ( currentLockMode == LockMode.WRITE
|
||||
|| currentLockMode == LockMode.PESSIMISTIC_WRITE
|
||||
|| currentLockMode == LockMode.PESSIMISTIC_READ ) {
|
||||
// our transaction should already hold the exclusive lock on
|
||||
// the underlying row - so READ should be sufficient.
|
||||
//
|
||||
|
@ -239,7 +236,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
source.setReadOnly( result, true );
|
||||
}
|
||||
else {
|
||||
source.setReadOnly( result, ( e == null ? source.isDefaultReadOnly() : e.isReadOnly() ) );
|
||||
source.setReadOnly( result, e == null ? source.isDefaultReadOnly() : e.isReadOnly() );
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -256,7 +253,8 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
final MappingMetamodelImplementor metamodel = factory.getRuntimeMetamodels().getMappingMetamodel();
|
||||
for ( Type type : types ) {
|
||||
if ( type.isCollectionType() ) {
|
||||
CollectionPersister collectionPersister = metamodel.getCollectionDescriptor( ( (CollectionType) type ).getRole() );
|
||||
final String role = ((CollectionType) type).getRole();
|
||||
CollectionPersister collectionPersister = metamodel.getCollectionDescriptor(role);
|
||||
if ( collectionPersister.hasCache() ) {
|
||||
final CollectionDataAccess cache = collectionPersister.getCacheAccessStrategy();
|
||||
final Object ck = cache.generateCacheKey(
|
||||
|
@ -271,8 +269,8 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
}
|
||||
}
|
||||
else if ( type.isComponentType() ) {
|
||||
CompositeType actype = (CompositeType) type;
|
||||
evictCachedCollections( actype.getSubtypes(), id, source );
|
||||
CompositeType compositeType = (CompositeType) type;
|
||||
evictCachedCollections( compositeType.getSubtypes(), id, source );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,15 +73,9 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
|
|||
|
||||
final ReplicationMode replicationMode = event.getReplicationMode();
|
||||
|
||||
final Object oldVersion;
|
||||
if ( replicationMode == ReplicationMode.EXCEPTION ) {
|
||||
//always do an INSERT, and let it fail by constraint violation
|
||||
oldVersion = null;
|
||||
}
|
||||
else {
|
||||
//what is the version on the database?
|
||||
oldVersion = persister.getCurrentVersion( id, source );
|
||||
}
|
||||
final Object oldVersion = replicationMode == ReplicationMode.EXCEPTION
|
||||
? null //always do an INSERT, and let it fail by constraint violation
|
||||
: persister.getCurrentVersion(id, source); //what is the version on the database?
|
||||
|
||||
if ( oldVersion != null ) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
|
@ -185,7 +179,7 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
|
|||
|
||||
source.getPersistenceContextInternal().addEntity(
|
||||
entity,
|
||||
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
|
||||
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
|
||||
null,
|
||||
source.generateEntityKey( id, persister ),
|
||||
version,
|
||||
|
|
|
@ -31,9 +31,6 @@ public class DefaultResolveNaturalIdEventListener
|
|||
extends AbstractLockUpgradeEventListener
|
||||
implements ResolveNaturalIdEventListener {
|
||||
|
||||
public static final Object REMOVED_ENTITY_MARKER = new Object();
|
||||
public static final Object INCONSISTENT_RTN_CLASS_MARKER = new Object();
|
||||
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultResolveNaturalIdEventListener.class );
|
||||
|
||||
@Override
|
||||
|
@ -94,10 +91,12 @@ public class DefaultResolveNaturalIdEventListener
|
|||
* @return The entity from the cache, or null.
|
||||
*/
|
||||
protected Object resolveFromCache(final ResolveNaturalIdEvent event) {
|
||||
return event.getSession().getPersistenceContextInternal().getNaturalIdResolutions().findCachedIdByNaturalId(
|
||||
event.getOrderedNaturalIdValues(),
|
||||
event.getEntityPersister()
|
||||
);
|
||||
return event.getSession().getPersistenceContextInternal()
|
||||
.getNaturalIdResolutions()
|
||||
.findCachedIdByNaturalId(
|
||||
event.getOrderedNaturalIdValues(),
|
||||
event.getEntityPersister()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,11 +109,10 @@ public class DefaultResolveNaturalIdEventListener
|
|||
*/
|
||||
protected Object loadFromDatasource(final ResolveNaturalIdEvent event) {
|
||||
final EventSource session = event.getSession();
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
final StatisticsImplementor statistics = factory.getStatistics();
|
||||
final boolean stats = statistics.isStatisticsEnabled();
|
||||
final StatisticsImplementor statistics = session.getFactory().getStatistics();
|
||||
final boolean statisticsEnabled = statistics.isStatisticsEnabled();
|
||||
long startTime = 0;
|
||||
if ( stats ) {
|
||||
if ( statisticsEnabled ) {
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
|
||||
|
@ -124,7 +122,7 @@ public class DefaultResolveNaturalIdEventListener
|
|||
session
|
||||
);
|
||||
|
||||
if ( stats ) {
|
||||
if ( statisticsEnabled ) {
|
||||
final long endTime = System.nanoTime();
|
||||
final long milliseconds = TimeUnit.MILLISECONDS.convert( endTime - startTime, TimeUnit.NANOSECONDS );
|
||||
statistics.naturalIdQueryExecuted(
|
||||
|
@ -135,10 +133,9 @@ public class DefaultResolveNaturalIdEventListener
|
|||
|
||||
//PK can be null if the entity doesn't exist
|
||||
if (pk != null) {
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
persistenceContext.getNaturalIdResolutions().cacheResolutionFromLoad(
|
||||
pk, event.getOrderedNaturalIdValues(), event.getEntityPersister()
|
||||
);
|
||||
session.getPersistenceContextInternal()
|
||||
.getNaturalIdResolutions()
|
||||
.cacheResolutionFromLoad( pk, event.getOrderedNaturalIdValues(), event.getEntityPersister() );
|
||||
}
|
||||
|
||||
return pk;
|
||||
|
|
|
@ -23,12 +23,9 @@ public class DefaultSaveEventListener extends DefaultSaveOrUpdateEventListener {
|
|||
// this implementation is supposed to tolerate incorrect unsaved-value
|
||||
// mappings, for the purpose of backward-compatibility
|
||||
EntityEntry entry = event.getSession().getPersistenceContextInternal().getEntry( event.getEntity() );
|
||||
if ( entry!=null && entry.getStatus() != Status.DELETED ) {
|
||||
return entityIsPersistent(event);
|
||||
}
|
||||
else {
|
||||
return entityIsTransient(event);
|
||||
}
|
||||
return entry != null && entry.getStatus() != Status.DELETED
|
||||
? entityIsPersistent(event)
|
||||
: entityIsTransient(event);
|
||||
}
|
||||
|
||||
protected Object saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {
|
||||
|
@ -36,15 +33,15 @@ public class DefaultSaveEventListener extends DefaultSaveOrUpdateEventListener {
|
|||
return super.saveWithGeneratedOrRequestedId(event);
|
||||
}
|
||||
else {
|
||||
return saveWithRequestedId(
|
||||
event.getEntity(),
|
||||
event.getRequestedId(),
|
||||
event.getEntityName(),
|
||||
null,
|
||||
event.getSession()
|
||||
return saveWithRequestedId(
|
||||
event.getEntity(),
|
||||
event.getRequestedId(),
|
||||
event.getEntityName(),
|
||||
null,
|
||||
event.getSession()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
|
||||
|
|
|
@ -47,7 +47,6 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
* @param event The update event to be handled.
|
||||
*/
|
||||
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
|
||||
final SessionImplementor source = event.getSession();
|
||||
final Object object = event.getObject();
|
||||
final Object requestedId = event.getRequestedId();
|
||||
|
||||
|
@ -59,6 +58,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
}
|
||||
}
|
||||
|
||||
final SessionImplementor source = event.getSession();
|
||||
// For an uninitialized proxy, noop, don't even need to return an id, since it is never a save()
|
||||
if ( reassociateIfUninitializedProxy( object, source ) ) {
|
||||
LOG.trace( "Reassociated uninitialized proxy" );
|
||||
|
@ -220,9 +220,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
EntityPersister persister = session.getEntityPersister( event.getEntityName(), entity );
|
||||
|
||||
event.setRequestedId(
|
||||
getUpdateId(
|
||||
entity, persister, event.getRequestedId(), session
|
||||
)
|
||||
getUpdateId( entity, persister, event.getRequestedId(), session )
|
||||
);
|
||||
|
||||
performUpdate( event, entity, persister );
|
||||
|
@ -279,9 +277,10 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
}
|
||||
|
||||
final EventSource source = event.getSession();
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
|
||||
final EntityKey key = source.generateEntityKey( event.getRequestedId(), persister );
|
||||
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
persistenceContext.checkUniqueness( key, entity );
|
||||
|
||||
if ( invokeUpdateLifecycle( entity, persister, source ) ) {
|
||||
|
@ -307,7 +306,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
|
||||
persistenceContext.addEntity(
|
||||
entity,
|
||||
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
|
||||
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
|
||||
null, // cachedState,
|
||||
key,
|
||||
persister.getVersion( entity ),
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.type.CollectionType;
|
||||
|
@ -32,8 +33,10 @@ public class DirtyCollectionSearchVisitor extends AbstractVisitor {
|
|||
super( session );
|
||||
EnhancementAsProxyLazinessInterceptor interceptor = null;
|
||||
if ( entity instanceof PersistentAttributeInterceptable ) {
|
||||
if ( ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor() instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||
interceptor = (EnhancementAsProxyLazinessInterceptor) ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||
PersistentAttributeInterceptor attributeInterceptor =
|
||||
((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
|
||||
if ( attributeInterceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||
interceptor = (EnhancementAsProxyLazinessInterceptor) attributeInterceptor;
|
||||
}
|
||||
}
|
||||
this.interceptor = interceptor;
|
||||
|
@ -62,7 +65,7 @@ public class DirtyCollectionSearchVisitor extends AbstractVisitor {
|
|||
// we now always call wrap() before getting to here)
|
||||
// return ( ! (obj instanceof PersistentCollection) ) ?
|
||||
//true : searchForDirtyCollections( (PersistentCollection) obj, type );
|
||||
persistentCollection = (PersistentCollection) collection;
|
||||
persistentCollection = (PersistentCollection<?>) collection;
|
||||
}
|
||||
|
||||
if ( persistentCollection.isDirty() ) { //we need to check even if it was not initialized, because of delayed adds!
|
||||
|
|
|
@ -76,7 +76,7 @@ public final class EntityCopyAllowedLoggedObserver implements EntityCopyObserver
|
|||
}
|
||||
if ( detachedEntitiesForManaged == null ) {
|
||||
// There were no existing representations for this particular managed entity;
|
||||
detachedEntitiesForManaged = new IdentitySet();
|
||||
detachedEntitiesForManaged = new IdentitySet<>();
|
||||
managedToMergeEntitiesXref.put( managedEntity, detachedEntitiesForManaged );
|
||||
incrementEntityNameCount( entityName );
|
||||
}
|
||||
|
@ -117,13 +117,11 @@ public final class EntityCopyAllowedLoggedObserver implements EntityCopyObserver
|
|||
// Log the summary.
|
||||
if ( countsByEntityName != null ) {
|
||||
for ( Map.Entry<String, Integer> entry : countsByEntityName.entrySet() ) {
|
||||
final String entityName = entry.getKey();
|
||||
final int count = entry.getValue();
|
||||
LOG.debug(
|
||||
String.format(
|
||||
"Summary: number of %s entities with multiple representations merged: %d",
|
||||
entityName,
|
||||
count
|
||||
entry.getKey(),
|
||||
entry.getValue()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -135,7 +133,7 @@ public final class EntityCopyAllowedLoggedObserver implements EntityCopyObserver
|
|||
if ( managedToMergeEntitiesXref != null ) {
|
||||
for ( Map.Entry<Object,Set<Object>> entry : managedToMergeEntitiesXref.entrySet() ) {
|
||||
Object managedEntity = entry.getKey();
|
||||
Set mergeEntities = entry.getValue();
|
||||
Set<Object> mergeEntities = entry.getValue();
|
||||
StringBuilder sb = new StringBuilder( "Details: merged ")
|
||||
.append( mergeEntities.size() )
|
||||
.append( " representations of the same entity " )
|
||||
|
@ -163,11 +161,8 @@ public final class EntityCopyAllowedLoggedObserver implements EntityCopyObserver
|
|||
}
|
||||
|
||||
private String getManagedOrDetachedEntityString(Object managedEntity, Object mergeEntity ) {
|
||||
if ( mergeEntity == managedEntity) {
|
||||
return "Managed: [" + mergeEntity + "]";
|
||||
}
|
||||
else {
|
||||
return "Detached: [" + mergeEntity + "]";
|
||||
}
|
||||
return mergeEntity == managedEntity
|
||||
? "Managed: [" + mergeEntity + "]"
|
||||
: "Detached: [" + mergeEntity + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,15 +34,18 @@ public class EntityCopyObserverFactoryInitiator implements StandardServiceInitia
|
|||
@Override
|
||||
public EntityCopyObserverFactory initiateService(final Map<String, Object> configurationValues, final ServiceRegistryImplementor registry) {
|
||||
final Object value = getConfigurationValue( configurationValues );
|
||||
if ( value.equals( EntityCopyNotAllowedObserver.SHORT_NAME ) || value.equals( EntityCopyNotAllowedObserver.class.getName() ) ) {
|
||||
if ( value.equals( EntityCopyNotAllowedObserver.SHORT_NAME )
|
||||
|| value.equals( EntityCopyNotAllowedObserver.class.getName() ) ) {
|
||||
LOG.debugf( "Configured EntityCopyObserver strategy: %s", EntityCopyNotAllowedObserver.SHORT_NAME );
|
||||
return EntityCopyNotAllowedObserver.FACTORY_OF_SELF;
|
||||
}
|
||||
else if ( value.equals( EntityCopyAllowedObserver.SHORT_NAME ) || value.equals( EntityCopyAllowedObserver.class.getName() ) ) {
|
||||
else if ( value.equals( EntityCopyAllowedObserver.SHORT_NAME )
|
||||
|| value.equals( EntityCopyAllowedObserver.class.getName() ) ) {
|
||||
LOG.debugf( "Configured EntityCopyObserver strategy: %s", EntityCopyAllowedObserver.SHORT_NAME );
|
||||
return EntityCopyAllowedObserver.FACTORY_OF_SELF;
|
||||
}
|
||||
else if ( value.equals( EntityCopyAllowedLoggedObserver.SHORT_NAME ) || value.equals( EntityCopyAllowedLoggedObserver.class.getName() ) ) {
|
||||
else if ( value.equals( EntityCopyAllowedLoggedObserver.SHORT_NAME )
|
||||
|| value.equals( EntityCopyAllowedLoggedObserver.class.getName() ) ) {
|
||||
LOG.debugf( "Configured EntityCopyObserver strategy: %s", EntityCopyAllowedLoggedObserver.SHORT_NAME );
|
||||
return EntityCopyAllowedLoggedObserver.FACTORY_OF_SELF;
|
||||
}
|
||||
|
@ -50,7 +53,8 @@ public class EntityCopyObserverFactoryInitiator implements StandardServiceInitia
|
|||
//We load an "example instance" just to get its Class;
|
||||
//this might look excessive, but it also happens to test eagerly (at boot) that we can actually construct these
|
||||
//and that they are indeed of the right type.
|
||||
EntityCopyObserver exampleInstance = registry.getService( StrategySelector.class ).resolveStrategy( EntityCopyObserver.class, value );
|
||||
EntityCopyObserver exampleInstance = registry.getService( StrategySelector.class )
|
||||
.resolveStrategy( EntityCopyObserver.class, value );
|
||||
Class<?> observerType = exampleInstance.getClass();
|
||||
LOG.debugf( "Configured EntityCopyObserver is a custom implementation of type %s", observerType.getName() );
|
||||
return new EntityObserversFactoryFromClass( observerType );
|
||||
|
@ -58,15 +62,15 @@ public class EntityCopyObserverFactoryInitiator implements StandardServiceInitia
|
|||
}
|
||||
|
||||
private Object getConfigurationValue(final Map<?,?> configurationValues) {
|
||||
final Object o = configurationValues.get( AvailableSettings.MERGE_ENTITY_COPY_OBSERVER );
|
||||
if ( o == null ) {
|
||||
final Object value = configurationValues.get( AvailableSettings.MERGE_ENTITY_COPY_OBSERVER );
|
||||
if ( value == null ) {
|
||||
return EntityCopyNotAllowedObserver.SHORT_NAME; //default
|
||||
}
|
||||
else if ( o instanceof String ) {
|
||||
return o.toString().trim();
|
||||
else if ( value instanceof String ) {
|
||||
return value.toString().trim();
|
||||
}
|
||||
else {
|
||||
return o;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.event.internal;
|
||||
|
||||
public class EventUtil {
|
||||
class EventUtil {
|
||||
public static String getLoggableName(String entityName, Object entity) {
|
||||
return entityName == null ? entity.getClass().getName() : entityName;
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ public class FlushVisitor extends AbstractVisitor {
|
|||
}
|
||||
|
||||
if ( collection != null ) {
|
||||
final PersistentCollection<?> coll;
|
||||
final EventSource session = getSession();
|
||||
final PersistentCollection<?> coll;
|
||||
if ( type.hasHolder() ) {
|
||||
coll = session.getPersistenceContextInternal().getCollectionHolder(collection);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class FlushVisitor extends AbstractVisitor {
|
|||
return null;
|
||||
}
|
||||
|
||||
Collections.processReachableCollection( coll, type, owner, session);
|
||||
Collections.processReachableCollection( coll, type, owner, session );
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -73,7 +73,7 @@ import org.hibernate.pretty.MessageHelper;
|
|||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class MergeContext implements Map {
|
||||
public class MergeContext implements Map<Object,Object> {
|
||||
|
||||
private final EventSource session;
|
||||
private final EntityCopyObserver entityCopyObserver;
|
||||
|
@ -146,7 +146,7 @@ public class MergeContext implements Map {
|
|||
*
|
||||
* @see Collections#unmodifiableSet(Set)
|
||||
*/
|
||||
public Set entrySet() {
|
||||
public Set<Map.Entry<Object,Object>> entrySet() {
|
||||
return Collections.unmodifiableSet( mergeToManagedEntityXref.entrySet() );
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ public class MergeContext implements Map {
|
|||
*
|
||||
* @see Collections#unmodifiableSet(Set)
|
||||
*/
|
||||
public Set keySet() {
|
||||
public Set<Object> keySet() {
|
||||
return Collections.unmodifiableSet( mergeToManagedEntityXref.keySet() );
|
||||
}
|
||||
|
||||
|
@ -284,9 +284,8 @@ public class MergeContext implements Map {
|
|||
* but associated value in <code>map</code> is different from the previous value in this MergeContext.
|
||||
* @throws IllegalStateException if internal cross-references are out of sync,
|
||||
*/
|
||||
public void putAll(Map map) {
|
||||
for ( Object o : map.entrySet() ) {
|
||||
Entry entry = (Entry) o;
|
||||
public void putAll(Map<?,?> map) {
|
||||
for ( Entry<?,?> entry : map.entrySet() ) {
|
||||
put( entry.getKey(), entry.getValue() );
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +315,7 @@ public class MergeContext implements Map {
|
|||
*
|
||||
* @see Collections#unmodifiableSet(Set)
|
||||
*/
|
||||
public Collection values() {
|
||||
public Collection<Object> values() {
|
||||
return Collections.unmodifiableSet( managedToMergeEntityXref.keySet() );
|
||||
}
|
||||
|
||||
|
@ -364,7 +363,7 @@ public class MergeContext implements Map {
|
|||
*
|
||||
* @see Collections#unmodifiableMap(Map)
|
||||
*/
|
||||
public Map invertMap() {
|
||||
public Map<Object,Object> invertMap() {
|
||||
return Collections.unmodifiableMap( managedToMergeEntityXref );
|
||||
}
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ public class OnReplicateVisitor extends ReattachVisitor {
|
|||
reattachCollection( wrapper, type );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// else {
|
||||
// otherwise a null or brand new collection
|
||||
// this will also (inefficiently) handle arrays, which
|
||||
// have no snapshot, so we can't do any better
|
||||
//processArrayOrNewCollection(collection, type);
|
||||
}
|
||||
// }
|
||||
|
||||
return null;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ public class OnUpdateVisitor extends ReattachVisitor {
|
|||
}
|
||||
}
|
||||
else {
|
||||
// null or brand new collection
|
||||
// null or brand-new collection
|
||||
// this will also (inefficiently) handle arrays, which have
|
||||
// no snapshot, so we can't do any better
|
||||
removeCollection(persister, collectionKey, session);
|
||||
|
|
|
@ -29,15 +29,13 @@ public class PostUpdateEventListenerStandardImpl implements PostUpdateEventListe
|
|||
|
||||
@Override
|
||||
public void onPostUpdate(PostUpdateEvent event) {
|
||||
Object entity = event.getEntity();
|
||||
EventSource eventSource = event.getSession();
|
||||
handlePostUpdate(entity, eventSource);
|
||||
handlePostUpdate( event.getEntity(), event.getSession() );
|
||||
}
|
||||
|
||||
private void handlePostUpdate(Object entity, EventSource source) {
|
||||
EntityEntry entry = source.getPersistenceContextInternal().getEntry( entity );
|
||||
// mimic the preUpdate filter
|
||||
if ( Status.DELETED != entry.getStatus()) {
|
||||
if ( Status.DELETED != entry.getStatus() ) {
|
||||
callbackRegistry.postUpdate(entity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public abstract class ProxyVisitor extends AbstractVisitor {
|
|||
|
||||
Object processEntity(Object value, EntityType entityType) throws HibernateException {
|
||||
|
||||
if (value!=null) {
|
||||
if ( value != null ) {
|
||||
getSession().getPersistenceContext().reassociateIfUninitializedProxy(value);
|
||||
// if it is an initialized proxy, let cascade
|
||||
// handle it later on
|
||||
|
@ -39,17 +39,19 @@ public abstract class ProxyVisitor extends AbstractVisitor {
|
|||
* was snapshotted and detached?
|
||||
*/
|
||||
protected static boolean isOwnerUnchanged(
|
||||
final CollectionPersister persister, final Object id, final PersistentCollection<?> snapshot
|
||||
final CollectionPersister persister,
|
||||
final Object id,
|
||||
final PersistentCollection<?> snapshot
|
||||
) {
|
||||
return isCollectionSnapshotValid(snapshot) &&
|
||||
persister.getRole().equals( snapshot.getRole() ) &&
|
||||
id.equals( snapshot.getKey() );
|
||||
return isCollectionSnapshotValid(snapshot)
|
||||
&& persister.getRole().equals( snapshot.getRole() )
|
||||
&& id.equals( snapshot.getKey() );
|
||||
}
|
||||
|
||||
private static boolean isCollectionSnapshotValid(PersistentCollection<?> snapshot) {
|
||||
return snapshot != null &&
|
||||
snapshot.getRole() != null &&
|
||||
snapshot.getKey() != null;
|
||||
return snapshot != null
|
||||
&& snapshot.getRole() != null
|
||||
&& snapshot.getKey() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +60,7 @@ public abstract class ProxyVisitor extends AbstractVisitor {
|
|||
* wrapper
|
||||
*/
|
||||
protected void reattachCollection(PersistentCollection<?> collection, CollectionType type)
|
||||
throws HibernateException {
|
||||
throws HibernateException {
|
||||
final EventSource session = getSession();
|
||||
if ( collection.wasInitialized() ) {
|
||||
final CollectionPersister persister = session.getFactory()
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLaziness
|
|||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -48,19 +49,14 @@ public class WrapVisitor extends ProxyVisitor {
|
|||
Object processCollection(Object collection, CollectionType collectionType)
|
||||
throws HibernateException {
|
||||
|
||||
if ( collection == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( collection == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
|
||||
if ( collection == null || collection == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( collection instanceof PersistentCollection ) {
|
||||
final PersistentCollection<?> coll = (PersistentCollection<?>) collection;
|
||||
final SessionImplementor session = getSession();
|
||||
|
||||
if ( coll.setCurrentSession( session ) ) {
|
||||
if ( coll.setCurrentSession( getSession() ) ) {
|
||||
reattachCollection( coll, collectionType );
|
||||
}
|
||||
|
||||
|
@ -103,7 +99,9 @@ public class WrapVisitor extends ProxyVisitor {
|
|||
}
|
||||
else {
|
||||
if ( entity instanceof PersistentAttributeInterceptable ) {
|
||||
if ( ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor() instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||
PersistentAttributeInterceptor attributeInterceptor =
|
||||
((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
|
||||
if ( attributeInterceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.hibernate.event.service.spi.EventListenerRegistrationException;
|
|||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.jpa.event.internal.CallbackRegistryImplementor;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
|
||||
import static org.hibernate.event.spi.EventType.AUTO_FLUSH;
|
||||
import static org.hibernate.event.spi.EventType.CLEAR;
|
||||
|
@ -346,12 +345,11 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
|
|||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public <T> void prepareListeners(
|
||||
EventType<T> type,
|
||||
T defaultListener,
|
||||
Function<EventType<T>,EventListenerGroupImpl<T>> groupCreator) {
|
||||
final EventListenerGroupImpl listenerGroup = groupCreator.apply( type );
|
||||
final EventListenerGroupImpl<T> listenerGroup = groupCreator.apply( type );
|
||||
|
||||
if ( defaultListener != null ) {
|
||||
listenerGroup.appendListener( defaultListener );
|
||||
|
@ -365,18 +363,17 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
|
|||
return (EventListenerGroup<T>) listenerGroupMap.get( eventType );
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public EventListenerRegistry buildRegistry(Map<String, EventType> registeredEventTypes) {
|
||||
public EventListenerRegistry buildRegistry(Map<String, EventType<?>> registeredEventTypes) {
|
||||
// validate contiguity of the event-type ordinals and build the EventListenerGroups array
|
||||
|
||||
final ArrayList<EventType> eventTypeList = new ArrayList<>( registeredEventTypes.values() );
|
||||
final ArrayList<EventType<?>> eventTypeList = new ArrayList<>( registeredEventTypes.values() );
|
||||
eventTypeList.sort( Comparator.comparing( EventType::ordinal ) );
|
||||
|
||||
final EventListenerGroup[] eventListeners = new EventListenerGroup[ eventTypeList.size() ];
|
||||
final EventListenerGroup<?>[] eventListeners = new EventListenerGroup[ eventTypeList.size() ];
|
||||
|
||||
int previous = -1;
|
||||
for ( int i = 0; i < eventTypeList.size(); i++ ) {
|
||||
final EventType eventType = eventTypeList.get( i );
|
||||
final EventType<?> eventType = eventTypeList.get( i );
|
||||
|
||||
assert i == eventType.ordinal();
|
||||
assert i - 1 == previous;
|
||||
|
|
|
@ -61,15 +61,19 @@ public abstract class AbstractCollectionEvent extends AbstractEvent {
|
|||
|
||||
protected static Object getOwnerIdOrNull(Object owner, EventSource source ) {
|
||||
EntityEntry ownerEntry = source.getPersistenceContextInternal().getEntry( owner );
|
||||
return ( ownerEntry == null ? null : ownerEntry.getId() );
|
||||
return ownerEntry == null ? null : ownerEntry.getId();
|
||||
}
|
||||
|
||||
protected static String getAffectedOwnerEntityName(CollectionPersister collectionPersister, Object affectedOwner, EventSource source ) {
|
||||
protected static String getAffectedOwnerEntityName(
|
||||
CollectionPersister collectionPersister,
|
||||
Object affectedOwner,
|
||||
EventSource source ) {
|
||||
|
||||
// collectionPersister should not be null, but we don't want to throw
|
||||
// an exception if it is null
|
||||
String entityName =
|
||||
( collectionPersister == null ? null : collectionPersister.getOwnerEntityPersister().getEntityName() );
|
||||
String entityName = collectionPersister == null
|
||||
? null
|
||||
: collectionPersister.getOwnerEntityPersister().getEntityName();
|
||||
if ( affectedOwner != null ) {
|
||||
EntityEntry ee = source.getPersistenceContextInternal().getEntry( affectedOwner );
|
||||
if ( ee != null && ee.getEntityName() != null) {
|
||||
|
|
|
@ -14,15 +14,15 @@ import java.util.Set;
|
|||
*/
|
||||
public class AutoFlushEvent extends FlushEvent {
|
||||
|
||||
private Set querySpaces;
|
||||
private Set<String> querySpaces;
|
||||
private boolean flushRequired;
|
||||
|
||||
public AutoFlushEvent(Set querySpaces, EventSource source) {
|
||||
public AutoFlushEvent(Set<String> querySpaces, EventSource source) {
|
||||
super(source);
|
||||
this.querySpaces = querySpaces;
|
||||
}
|
||||
|
||||
public Set getQuerySpaces() {
|
||||
public Set<String> getQuerySpaces() {
|
||||
return querySpaces;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.hibernate.service.spi.Stoppable;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EventEngine {
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final Map<String,EventType> registeredEventTypes;
|
||||
|
||||
private final Map<String,EventType<?>> registeredEventTypes;
|
||||
private final EventListenerRegistry listenerRegistry;
|
||||
|
||||
private final CallbackRegistryImplementor callbackRegistry;
|
||||
|
@ -55,14 +55,14 @@ public class EventEngine {
|
|||
sessionFactory.getSessionFactoryOptions().isJpaBootstrap()
|
||||
);
|
||||
|
||||
final Map<String,EventType> eventTypes = new HashMap<>();
|
||||
final Map<String,EventType<?>> eventTypes = new HashMap<>();
|
||||
EventType.registerStandardTypes( eventTypes );
|
||||
|
||||
final EventEngineContributions contributionManager = new EventEngineContributions() {
|
||||
@Override
|
||||
public <T> EventType<T> findEventType(String name) {
|
||||
//noinspection unchecked
|
||||
return eventTypes.get( name );
|
||||
return (EventType<T>) eventTypes.get( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,13 +101,12 @@ public class EventEngine {
|
|||
return eventType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> EventType<T> contributeEventType(String name, Class<T> listenerRole, T... defaultListeners) {
|
||||
@Override @SafeVarargs
|
||||
public final <T> EventType<T> contributeEventType(String name, Class<T> listenerRole, T... defaultListeners) {
|
||||
final EventType<T> eventType = contributeEventType( name, listenerRole );
|
||||
|
||||
if ( defaultListeners != null ) {
|
||||
final EventListenerGroup<T> listenerGroup = listenerRegistryBuilder.getListenerGroup( eventType );
|
||||
listenerGroup.appendListeners( defaultListeners );
|
||||
listenerRegistryBuilder.getListenerGroup( eventType ).appendListeners( defaultListeners );
|
||||
}
|
||||
|
||||
return eventType;
|
||||
|
@ -125,9 +124,10 @@ public class EventEngine {
|
|||
}
|
||||
};
|
||||
|
||||
final Collection<EventEngineContributor> discoveredContributors = sessionFactory.getServiceRegistry()
|
||||
.getService( ClassLoaderService.class )
|
||||
.loadJavaServices( EventEngineContributor.class );
|
||||
final Collection<EventEngineContributor> discoveredContributors =
|
||||
sessionFactory.getServiceRegistry()
|
||||
.getService( ClassLoaderService.class )
|
||||
.loadJavaServices( EventEngineContributor.class );
|
||||
if ( CollectionHelper.isNotEmpty( discoveredContributors ) ) {
|
||||
for ( EventEngineContributor contributor : discoveredContributors ) {
|
||||
contributor.contribute( contributionManager );
|
||||
|
@ -139,13 +139,12 @@ public class EventEngine {
|
|||
}
|
||||
|
||||
public Collection<EventType<?>> getRegisteredEventTypes() {
|
||||
//noinspection unchecked,rawtypes
|
||||
return (Collection) registeredEventTypes.values();
|
||||
return registeredEventTypes.values();
|
||||
}
|
||||
|
||||
public <T> EventType<T> findRegisteredEventType(String name) {
|
||||
//noinspection unchecked
|
||||
return registeredEventTypes.get( name );
|
||||
return (EventType<T>) registeredEventTypes.get( name );
|
||||
}
|
||||
|
||||
public EventListenerRegistry getListenerRegistry() {
|
||||
|
|
|
@ -26,7 +26,7 @@ public final class EventType<T> {
|
|||
/**
|
||||
* Used to assign ordinals for the standard event-types
|
||||
*/
|
||||
private static AtomicInteger STANDARD_TYPE_COUNTER = new AtomicInteger();
|
||||
private static final AtomicInteger STANDARD_TYPE_COUNTER = new AtomicInteger();
|
||||
|
||||
public static final EventType<LoadEventListener> LOAD = create( "load", LoadEventListener.class );
|
||||
public static final EventType<ResolveNaturalIdEventListener> RESOLVE_NATURAL_ID = create( "resolve-natural-id", ResolveNaturalIdEventListener.class );
|
||||
|
@ -83,26 +83,22 @@ public final class EventType<T> {
|
|||
* Maintain a map of {@link EventType} instances keyed by name for lookup by name as well as {@link #values()}
|
||||
* resolution.
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "Convert2Lambda"})
|
||||
private static final Map<String,EventType> STANDARD_TYPE_BY_NAME_MAP = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Map<String, EventType>>() {
|
||||
@Override
|
||||
public Map<String, EventType> run() {
|
||||
final Map<String, EventType> typeByNameMap = new HashMap<>();
|
||||
for ( Field field : EventType.class.getDeclaredFields() ) {
|
||||
if ( EventType.class.isAssignableFrom( field.getType() ) ) {
|
||||
try {
|
||||
final EventType typeField = (EventType) field.get( null );
|
||||
typeByNameMap.put( typeField.eventName(), typeField );
|
||||
}
|
||||
catch (Exception t) {
|
||||
throw new HibernateException( "Unable to initialize EventType map", t );
|
||||
}
|
||||
private static final Map<String,EventType<?>> STANDARD_TYPE_BY_NAME_MAP = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Map<String, EventType<?>>>) () -> {
|
||||
final Map<String, EventType<?>> typeByNameMap = new HashMap<>();
|
||||
for ( Field field : EventType.class.getDeclaredFields() ) {
|
||||
if ( EventType.class.isAssignableFrom( field.getType() ) ) {
|
||||
try {
|
||||
final EventType<?> typeField = (EventType<?>) field.get( null );
|
||||
typeByNameMap.put( typeField.eventName(), typeField );
|
||||
}
|
||||
catch (Exception t) {
|
||||
throw new HibernateException( "Unable to initialize EventType map", t );
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap( typeByNameMap );
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap( typeByNameMap );
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -138,8 +134,7 @@ public final class EventType<T> {
|
|||
/**
|
||||
* Get a collection of all the standard {@link EventType} instances.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static Collection<EventType> values() {
|
||||
public static Collection<EventType<?>> values() {
|
||||
return STANDARD_TYPE_BY_NAME_MAP.values();
|
||||
}
|
||||
|
||||
|
@ -148,8 +143,7 @@ public final class EventType<T> {
|
|||
*
|
||||
* Simply copy the values into its (passed) Map
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
static void registerStandardTypes(Map<String, EventType> eventTypes) {
|
||||
static void registerStandardTypes(Map<String, EventType<?>> eventTypes) {
|
||||
eventTypes.putAll( STANDARD_TYPE_BY_NAME_MAP );
|
||||
}
|
||||
|
||||
|
@ -180,7 +174,7 @@ public final class EventType<T> {
|
|||
*
|
||||
* For the total number of types, see {@link #values()}
|
||||
*
|
||||
* @return An unique ordinal for this {@link EventType}, starting at 0 and up to the number of distinct events
|
||||
* @return A unique ordinal for this {@link EventType}, starting at 0 and up to the number of distinct events
|
||||
*/
|
||||
public int ordinal() {
|
||||
return ordinal;
|
||||
|
|
|
@ -12,14 +12,14 @@ import org.hibernate.engine.spi.EntityEntry;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class FlushEntityEvent extends AbstractEvent {
|
||||
private Object entity;
|
||||
private final Object entity;
|
||||
private Object[] propertyValues;
|
||||
private Object[] databaseSnapshot;
|
||||
private int[] dirtyProperties;
|
||||
private boolean hasDirtyCollection;
|
||||
private boolean dirtyCheckPossible;
|
||||
private boolean dirtyCheckHandledByInterceptor;
|
||||
private EntityEntry entityEntry;
|
||||
private final EntityEntry entityEntry;
|
||||
|
||||
public FlushEntityEvent(EventSource source, Object entity, EntityEntry entry) {
|
||||
super(source);
|
||||
|
|
|
@ -41,7 +41,7 @@ public class LoadEvent extends AbstractEvent {
|
|||
private String entityClassName;
|
||||
private Object instanceToLoad;
|
||||
private LockOptions lockOptions;
|
||||
private boolean isAssociationFetch;
|
||||
private final boolean isAssociationFetch;
|
||||
private Object result;
|
||||
private PostLoadEvent postLoadEvent;
|
||||
private Boolean readOnly;
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.hibernate.LockOptions;
|
|||
public class LockEvent extends AbstractEvent {
|
||||
|
||||
private Object object;
|
||||
private LockOptions lockOptions;
|
||||
private final LockOptions lockOptions;
|
||||
private String entityName;
|
||||
|
||||
public LockEvent(String entityName, Object original, LockMode lockMode, EventSource source) {
|
||||
|
|
|
@ -14,10 +14,10 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class PostDeleteEvent extends AbstractEvent {
|
||||
private Object entity;
|
||||
private EntityPersister persister;
|
||||
private Object id;
|
||||
private Object[] deletedState;
|
||||
private final Object entity;
|
||||
private final EntityPersister persister;
|
||||
private final Object id;
|
||||
private final Object[] deletedState;
|
||||
|
||||
public PostDeleteEvent(
|
||||
Object entity,
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.hibernate.LockOptions;
|
|||
*/
|
||||
public class RefreshEvent extends AbstractEvent {
|
||||
|
||||
private Object object;
|
||||
private final Object object;
|
||||
private String entityName;
|
||||
|
||||
private LockOptions lockOptions = new LockOptions().setLockMode(LockMode.READ);
|
||||
|
|
Loading…
Reference in New Issue