finally fix the warnings and typecasts in DefaultMergeEventListener

by using MergeContext instead of (raw!) Map
This commit is contained in:
Gavin King 2022-01-30 13:15:37 +01:00
parent b75613cff1
commit 7570d15291
11 changed files with 42 additions and 43 deletions

View File

@ -17,6 +17,7 @@
import org.hibernate.TransientPropertyValueException; import org.hibernate.TransientPropertyValueException;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ForeignKeys; import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.event.spi.MergeContext;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
@ -258,7 +259,7 @@ public void cascade(
boolean isCascadeDeleteEnabled) boolean isCascadeDeleteEnabled)
throws HibernateException { throws HibernateException {
LOG.tracev( "Cascading to merge: {0}", entityName ); LOG.tracev( "Cascading to merge: {0}", entityName );
session.merge( entityName, child, (Map<?,?>) anything ); session.merge( entityName, child, (MergeContext) anything );
} }
@Override @Override

View File

@ -37,6 +37,7 @@
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.event.spi.MergeContext;
import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.jdbc.ReturningWork; import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work; import org.hibernate.jdbc.Work;
@ -1096,7 +1097,7 @@ public void forceFlush(EntityEntry e) throws HibernateException {
} }
@Override @Override
public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException { public void merge(String entityName, Object object, MergeContext copiedAlready) throws HibernateException {
delegate.merge( entityName, object, copiedAlready ); delegate.merge( entityName, object, copiedAlready );
} }

View File

@ -11,6 +11,7 @@
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.event.spi.MergeContext;
import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinator;
@ -77,7 +78,7 @@ default SessionImplementor getSession() {
* @deprecated OperationalContext should cover this overload I believe * @deprecated OperationalContext should cover this overload I believe
*/ */
@Deprecated @Deprecated
void merge(String entityName, Object object, Map copiedAlready) throws HibernateException; void merge(String entityName, Object object, MergeContext copiedAlready) throws HibernateException;
/** /**
* @deprecated OperationalContext should cover this overload I believe * @deprecated OperationalContext should cover this overload I believe

View File

@ -272,7 +272,7 @@ protected Object performSaveOrReplicate(
} }
if ( substitute ) { if ( substitute ) {
persister.setPropertyValues( entity, values ); persister.setValues( entity, values );
} }
TypeHelper.deepCopy( TypeHelper.deepCopy(
@ -355,7 +355,7 @@ private AbstractEntityInsertAction addInsertAction(
} }
} }
protected Map getMergeMap(Object anything) { protected Map<Object,Object> getMergeMap(Object anything) {
return null; return null;
} }
@ -377,7 +377,7 @@ protected boolean visitCollectionsBeforeSave(
Type[] types, Type[] types,
EventSource source) { EventSource source) {
WrapVisitor visitor = new WrapVisitor( entity, id, source ); WrapVisitor visitor = new WrapVisitor( entity, id, source );
// substitutes into values by side-effect // substitutes into values by side effect
visitor.processEntityPropertyValues( values, types ); visitor.processEntityPropertyValues( values, types );
return visitor.isSubstitutionRequired(); return visitor.isSubstitutionRequired();
} }
@ -454,7 +454,7 @@ protected void cascadeBeforeSave(
} }
/** /**
* Handles to calls needed to perform post-save cascades. * Handles calls needed to perform post-save cascades.
* *
* @param source The session from which the event originated. * @param source The session from which the event originated.
* @param persister The entity's persister instance. * @param persister The entity's persister instance.

View File

@ -29,6 +29,7 @@
import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EntityCopyObserver;
import org.hibernate.event.spi.EntityCopyObserverFactory; import org.hibernate.event.spi.EntityCopyObserverFactory;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.MergeContext;
import org.hibernate.event.spi.MergeEvent; import org.hibernate.event.spi.MergeEvent;
import org.hibernate.event.spi.MergeEventListener; import org.hibernate.event.spi.MergeEventListener;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
@ -37,7 +38,6 @@
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.stat.spi.StatisticsImplementor; import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.TypeHelper; import org.hibernate.type.TypeHelper;
@ -52,7 +52,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultMergeEventListener.class ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultMergeEventListener.class );
@Override @Override
protected Map getMergeMap(Object anything) { protected Map<Object,Object> getMergeMap(Object anything) {
return ( (MergeContext) anything ).invertMap(); return ( (MergeContext) anything ).invertMap();
} }
@ -87,9 +87,8 @@ private EntityCopyObserver createEntityCopyObserver(SessionFactoryImplementor se
* @param event The merge event to be handled. * @param event The merge event to be handled.
* *
*/ */
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException { public void onMerge(MergeEvent event, MergeContext copiedAlready) throws HibernateException {
final MergeContext copyCache = (MergeContext) copiedAlready;
final EventSource source = event.getSession(); final EventSource source = event.getSession();
final Object original = event.getOriginal(); final Object original = event.getOriginal();
@ -127,14 +126,14 @@ else if ( original instanceof PersistentAttributeInterceptable ) {
entity = original; entity = original;
} }
if ( copyCache.containsKey( entity ) && copyCache.isOperatedOn( entity ) ) { if ( ((MergeContext) copiedAlready).containsKey( entity ) && ((MergeContext) copiedAlready).isOperatedOn( entity ) ) {
LOG.trace( "Already in merge process" ); LOG.trace( "Already in merge process" );
event.setResult( entity ); event.setResult( entity );
} }
else { else {
if ( copyCache.containsKey( entity ) ) { if ( ((MergeContext) copiedAlready).containsKey( entity ) ) {
LOG.trace( "Already in copyCache; setting in merge process" ); LOG.trace( "Already in copyCache; setting in merge process" );
copyCache.setOperatedOn( entity, true ); ((MergeContext) copiedAlready).setOperatedOn( entity, true );
} }
event.setEntity( entity ); event.setEntity( entity );
EntityState entityState = null; EntityState entityState = null;
@ -167,13 +166,13 @@ else if ( original instanceof PersistentAttributeInterceptable ) {
switch ( entityState ) { switch ( entityState ) {
case DETACHED: case DETACHED:
entityIsDetached( event, copyCache ); entityIsDetached( event, (MergeContext) copiedAlready);
break; break;
case TRANSIENT: case TRANSIENT:
entityIsTransient( event, copyCache ); entityIsTransient( event, (MergeContext) copiedAlready);
break; break;
case PERSISTENT: case PERSISTENT:
entityIsPersistent( event, copyCache ); entityIsPersistent( event, (MergeContext) copiedAlready);
break; break;
default: //DELETED default: //DELETED
throw new ObjectDeletedException( throw new ObjectDeletedException(
@ -188,7 +187,7 @@ else if ( original instanceof PersistentAttributeInterceptable ) {
} }
protected void entityIsPersistent(MergeEvent event, Map copyCache) { protected void entityIsPersistent(MergeEvent event, MergeContext copyCache) {
LOG.trace( "Ignoring persistent instance" ); LOG.trace( "Ignoring persistent instance" );
//TODO: check that entry.getIdentifier().equals(requestedId) //TODO: check that entry.getIdentifier().equals(requestedId)
@ -197,7 +196,7 @@ protected void entityIsPersistent(MergeEvent event, Map copyCache) {
final EventSource source = event.getSession(); final EventSource source = event.getSession();
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
( (MergeContext) copyCache ).put( entity, entity, true ); //before cascade! copyCache.put( entity, entity, true ); //before cascade!
cascadeOnMerge( source, persister, entity, copyCache ); cascadeOnMerge( source, persister, entity, copyCache );
copyValues( persister, entity, entity, source, copyCache ); copyValues( persister, entity, entity, source, copyCache );
@ -205,7 +204,7 @@ protected void entityIsPersistent(MergeEvent event, Map copyCache) {
event.setResult( entity ); event.setResult( entity );
} }
protected void entityIsTransient(MergeEvent event, Map copyCache) { protected void entityIsTransient(MergeEvent event, MergeContext copyCache) {
LOG.trace( "Merging transient instance" ); LOG.trace( "Merging transient instance" );
@ -229,7 +228,7 @@ protected void entityIsTransient(MergeEvent event, Map copyCache) {
copy = session.instantiate( persister, id ); copy = session.instantiate( persister, id );
//before cascade! //before cascade!
( (MergeContext) copyCache ).put( entity, copy, true ); copyCache.put( entity, copy, true );
} }
// cascade first, so that all unsaved objects get their // cascade first, so that all unsaved objects get their
@ -261,7 +260,7 @@ private void saveTransientEntity(
String entityName, String entityName,
Object requestedId, Object requestedId,
EventSource source, EventSource source,
Map copyCache) { MergeContext copyCache) {
//this bit is only *really* absolutely necessary for handling //this bit is only *really* absolutely necessary for handling
//requestedId, but is also good if we merge multiple object //requestedId, but is also good if we merge multiple object
//graphs, since it helps ensure uniqueness //graphs, since it helps ensure uniqueness
@ -273,7 +272,7 @@ private void saveTransientEntity(
} }
} }
protected void entityIsDetached(MergeEvent event, Map copyCache) { protected void entityIsDetached(MergeEvent event, MergeContext copyCache) {
LOG.trace( "Merging detached instance" ); LOG.trace( "Merging detached instance" );
@ -317,7 +316,7 @@ protected void entityIsDetached(MergeEvent event, Map copyCache) {
} }
else { else {
// before cascade! // before cascade!
( (MergeContext) copyCache ).put( entity, result, true ); copyCache.put( entity, result, true );
final Object target = unproxyManagedForDetachedMerging( entity, result, persister, source ); final Object target = unproxyManagedForDetachedMerging( entity, result, persister, source );
@ -345,7 +344,7 @@ else if ( isVersionChanged( entity, source, persister, target ) ) {
copyValues( persister, entity, target, source, copyCache ); copyValues( persister, entity, target, source, copyCache );
//copyValues works by reflection, so explicitly mark the entity instance dirty //copyValues works by reflection, so explicitly mark the entity instance dirty
markInterceptorDirty( entity, target, persister ); markInterceptorDirty( entity, target );
event.setResult( result ); event.setResult( result );
} }
@ -390,7 +389,7 @@ private Object unproxyManagedForDetachedMerging(
return managed; return managed;
} }
private void markInterceptorDirty(final Object entity, final Object target, EntityPersister persister) { private void markInterceptorDirty(final Object entity, final Object target) {
// for enhanced entities, copy over the dirty attributes // for enhanced entities, copy over the dirty attributes
if ( entity instanceof SelfDirtinessTracker && target instanceof SelfDirtinessTracker ) { if ( entity instanceof SelfDirtinessTracker && target instanceof SelfDirtinessTracker ) {
// clear, because setting the embedded attributes dirties them // clear, because setting the embedded attributes dirties them
@ -446,7 +445,7 @@ protected void copyValues(
final Object entity, final Object entity,
final Object target, final Object target,
final SessionImplementor source, final SessionImplementor source,
final Map copyCache) { final MergeContext copyCache) {
final Object[] copiedValues = TypeHelper.replace( final Object[] copiedValues = TypeHelper.replace(
persister.getValues( entity ), persister.getValues( entity ),
persister.getValues( target ), persister.getValues( target ),
@ -456,7 +455,7 @@ protected void copyValues(
copyCache copyCache
); );
persister.setPropertyValues( target, copiedValues ); persister.setValues( target, copiedValues );
} }
protected void copyValues( protected void copyValues(
@ -464,7 +463,7 @@ protected void copyValues(
final Object entity, final Object entity,
final Object target, final Object target,
final SessionImplementor source, final SessionImplementor source,
final Map copyCache, final MergeContext copyCache,
final ForeignKeyDirection foreignKeyDirection) { final ForeignKeyDirection foreignKeyDirection) {
final Object[] copiedValues; final Object[] copiedValues;
@ -495,7 +494,7 @@ protected void copyValues(
); );
} }
persister.setPropertyValues( target, copiedValues ); persister.setValues( target, copiedValues );
} }
/** /**
@ -510,7 +509,7 @@ protected void cascadeOnMerge(
final EventSource source, final EventSource source,
final EntityPersister persister, final EntityPersister persister,
final Object entity, final Object entity,
final Map copyCache final MergeContext copyCache
) { ) {
final PersistenceContext persistenceContext = source.getPersistenceContextInternal(); final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
persistenceContext.incrementCascadeLevel(); persistenceContext.incrementCascadeLevel();

View File

@ -9,7 +9,7 @@
/** /**
* An observer for detection of multiple entity representations for a persistent entity being merged. * An observer for detection of multiple entity representations for a persistent entity being merged.
* *
* @see org.hibernate.event.internal.MergeContext * @see MergeContext
* *
* @author Gail Badner * @author Gail Badner
*/ */

View File

@ -39,7 +39,7 @@ public interface EventSource extends SessionImplementor {
/** /**
* Cascade merge an entity instance * Cascade merge an entity instance
*/ */
void merge(String entityName, Object object, Map copiedAlready) throws HibernateException; void merge(String entityName, Object object, MergeContext copiedAlready) throws HibernateException;
/** /**
* Cascade persist an entity instance * Cascade persist an entity instance
*/ */

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.event.internal; package org.hibernate.event.spi;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -12,8 +12,6 @@
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.hibernate.event.spi.EntityCopyObserver;
import org.hibernate.event.spi.EventSource;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
/** /**

View File

@ -6,8 +6,6 @@
*/ */
package org.hibernate.event.spi; package org.hibernate.event.spi;
import java.util.Map;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
/** /**
@ -29,6 +27,6 @@ public interface MergeEventListener {
* *
* @param event The merge event to be handled. * @param event The merge event to be handled.
*/ */
void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException; void onMerge(MergeEvent event, MergeContext copiedAlready) throws HibernateException;
} }

View File

@ -69,6 +69,7 @@
import org.hibernate.engine.spi.Status; import org.hibernate.engine.spi.Status;
import org.hibernate.engine.transaction.spi.TransactionImplementor; import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.engine.transaction.spi.TransactionObserver; import org.hibernate.engine.transaction.spi.TransactionObserver;
import org.hibernate.event.spi.MergeContext;
import org.hibernate.event.spi.AutoFlushEvent; import org.hibernate.event.spi.AutoFlushEvent;
import org.hibernate.event.spi.AutoFlushEventListener; import org.hibernate.event.spi.AutoFlushEventListener;
import org.hibernate.event.spi.ClearEvent; import org.hibernate.event.spi.ClearEvent;
@ -796,7 +797,7 @@ public <T> T merge(T object) throws HibernateException {
} }
@Override @Override
public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException { public void merge(String entityName, Object object, MergeContext copiedAlready) throws HibernateException {
checkOpenOrWaitingForAutoClose(); checkOpenOrWaitingForAutoClose();
fireMerge( copiedAlready, new MergeEvent( entityName, object, this ) ); fireMerge( copiedAlready, new MergeEvent( entityName, object, this ) );
} }
@ -822,10 +823,10 @@ private Object fireMerge(MergeEvent event) {
return event.getResult(); return event.getResult();
} }
private void fireMerge(final Map copiedAlready, final MergeEvent event) { private void fireMerge(final MergeContext mergeContext, final MergeEvent event) {
try { try {
pulseTransactionCoordinator(); pulseTransactionCoordinator();
fastSessionServices.eventListenerGroup_MERGE.fireEventOnEachListener( event, copiedAlready, MergeEventListener::onMerge ); fastSessionServices.eventListenerGroup_MERGE.fireEventOnEachListener( event, mergeContext, MergeEventListener::onMerge );
} }
catch ( ObjectDeletedException sse ) { catch ( ObjectDeletedException sse ) {
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) ); throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );

View File

@ -18,7 +18,7 @@
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.hibernate.event.internal.MergeContext; import org.hibernate.event.spi.MergeContext;
import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EntityCopyObserver;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;