Skip to content

code cleanups in DefaultMergeEventListener #10101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 1, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTracker;
import static org.hibernate.event.internal.EntityState.getEntityState;
import static org.hibernate.event.internal.EventUtil.getLoggableName;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;

/**
Expand Down Expand Up @@ -153,27 +154,21 @@ private void merge(MergeEvent event, MergeContext copiedAlready, Object entity)
final EventSource source = event.getSession();
// Check the persistence context for an entry relating to this
// entity to be merged...
final String entityName = event.getEntityName();
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
EntityEntry entry = persistenceContext.getEntry( entity );
final EntityState entityState;
final Object copiedId;
final Object originalId;
if ( entry == null ) {
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
final EntityPersister persister = source.getEntityPersister( entityName, entity );
originalId = persister.getIdentifier( entity, copiedAlready );
if ( originalId != null ) {
final EntityKey entityKey;
if ( persister.getIdentifierType() instanceof ComponentType ) {
/*
this is needed in case of composite id containing an association with a generated identifier, in such a case
generating the EntityKey will cause a NPE when trying to get the hashcode of the null id
*/
copiedId = copyCompositeTypeId(
originalId,
(ComponentType) persister.getIdentifierType(),
source,
copiedAlready
);
if ( persister.getIdentifierType() instanceof ComponentType compositeId ) {
// this is needed in case of a composite id containing an association with a generated identifier
// in such a case, generating the EntityKey will cause NPE when evaluating the hashcode of the null id
copiedId = copyCompositeTypeId( originalId, compositeId, source, copiedAlready );
entityKey = source.generateEntityKey( copiedId, persister );
}
else {
Expand All @@ -191,18 +186,18 @@ private void merge(MergeEvent event, MergeContext copiedAlready, Object entity)
entityState = EntityState.DETACHED;
}
else {
entityState = getEntityState( entity, event.getEntityName(), entry, source, false );
entityState = getEntityState( entity, entityName, entry, source, false );
}
}
else {
copiedId = null;
entityState = getEntityState( entity, event.getEntityName(), entry, source, false );
entityState = getEntityState( entity, entityName, entry, source, false );
}
}
else {
copiedId = null;
originalId = null;
entityState = getEntityState( entity, event.getEntityName(), entry, source, false );
entityState = getEntityState( entity, entityName, entry, source, false );
}

switch ( entityState ) {
Expand All @@ -217,22 +212,19 @@ private void merge(MergeEvent event, MergeContext copiedAlready, Object entity)
break;
default: //DELETED
if ( persistenceContext.getEntry( entity ) == null ) {
final EntityPersister persister = source.getEntityPersister( entityName, entity );
assert persistenceContext.containsDeletedUnloadedEntityKey(
source.generateEntityKey(
source.getEntityPersister( event.getEntityName(), entity )
.getIdentifier( entity, event.getSession() ),
source.getEntityPersister( event.getEntityName(), entity )
persister.getIdentifier( entity, event.getSession() ),
persister
)
);
source.getActionQueue().unScheduleUnloadedDeletion( entity );
entityIsDetached(event, copiedId, originalId, copiedAlready);
break;
}
throw new ObjectDeletedException(
"deleted instance passed to merge",
null,
EventUtil.getLoggableName( event.getEntityName(), entity)
);
throw new ObjectDeletedException( "deleted instance passed to merge",
originalId, getLoggableName( entityName, entity ) );
}
}

Expand All @@ -245,25 +237,33 @@ private static Object copyCompositeTypeId(
final Object idCopy = compositeType.deepCopy( id, factory );
final Type[] subtypes = compositeType.getSubtypes();
final Object[] propertyValues = compositeType.getPropertyValues( id );
final Object[] copyValues = compositeType.getPropertyValues( idCopy );
final Object[] copiedValues = compositeType.getPropertyValues( idCopy );
for ( int i = 0; i < subtypes.length; i++ ) {
final Type subtype = subtypes[i];
if ( subtype instanceof EntityType ) {
// the value of the copy in the MergeContext has the id assigned
final Object object = mergeContext.get( propertyValues[i] );
copyValues[i] = object == null ? subtype.deepCopy( propertyValues[i], factory ) : object;
}
else if ( subtype instanceof AnyType anyType ) {
copyValues[i] = copyCompositeTypeId( propertyValues[i], anyType, session, mergeContext );
}
else if ( subtype instanceof ComponentType componentType ) {
copyValues[i] = copyCompositeTypeId( propertyValues[i], componentType, session, mergeContext );
}
else {
copyValues[i] = subtype.deepCopy( propertyValues[i], factory );
}
copiedValues[i] = copy( session, mergeContext, subtypes[i], propertyValues[i], factory );
}
return compositeType.replacePropertyValues( idCopy, copiedValues, session );
}

private static Object copy(
EventSource session,
MergeContext mergeContext,
Type subtype,
Object propertyValue,
SessionFactoryImplementor factory) {
if ( subtype instanceof EntityType ) {
// the value of the copy in the MergeContext has the id assigned
final Object object = mergeContext.get( propertyValue );
return object == null ? subtype.deepCopy( propertyValue, factory ) : object;
}
else if ( subtype instanceof AnyType anyType ) {
return copyCompositeTypeId( propertyValue, anyType, session, mergeContext );
}
else if ( subtype instanceof ComponentType componentType ) {
return copyCompositeTypeId( propertyValue, componentType, session, mergeContext );
}
else {
return subtype.deepCopy( propertyValue, factory );
}
return compositeType.replacePropertyValues( idCopy, copyValues, session );
}

protected void entityIsPersistent(MergeEvent event, MergeContext copyCache) {
Expand Down
Loading