Skip to content

Commit 578023e

Browse files
committed
HHH-18553 change thrown exception type
and cleanups in DefaultDeleteEventListener Signed-off-by: Gavin King <[email protected]>
1 parent 7e4df3f commit 578023e

File tree

3 files changed

+37
-24
lines changed

3 files changed

+37
-24
lines changed

hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,23 @@ public class StaleObjectStateException extends StaleStateException {
2020

2121
/**
2222
* Constructs a {@code StaleObjectStateException} using the supplied information.
23-
* @param entityName The name of the entity
23+
*
24+
* @param entityName The name of the entity
2425
* @param identifier The identifier of the entity
2526
*/
2627
public StaleObjectStateException(String entityName, Object identifier) {
27-
super( "Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)" );
28+
this( entityName, identifier,
29+
"Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)" );
30+
}
31+
32+
/**
33+
* Constructs a {@code StaleObjectStateException} using the supplied information.
34+
*
35+
* @param entityName The name of the entity
36+
* @param identifier The identifier of the entity
37+
*/
38+
public StaleObjectStateException(String entityName, Object identifier, String message) {
39+
super( message );
2840
this.entityName = entityName;
2941
this.identifier = identifier;
3042
}

hibernate-core/src/main/java/org/hibernate/event/internal/DefaultDeleteEventListener.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.hibernate.CacheMode;
1010
import org.hibernate.HibernateException;
1111
import org.hibernate.LockMode;
12-
import org.hibernate.NonUniqueObjectException;
12+
import org.hibernate.StaleObjectStateException;
1313
import org.hibernate.TransientObjectException;
1414
import org.hibernate.action.internal.CollectionRemoveAction;
1515
import org.hibernate.action.internal.EntityDeleteAction;
@@ -22,7 +22,6 @@
2222
import org.hibernate.engine.internal.ForeignKeys;
2323
import org.hibernate.engine.internal.Nullability;
2424
import org.hibernate.engine.internal.Nullability.NullabilityCheckType;
25-
import org.hibernate.engine.spi.ActionQueue;
2625
import org.hibernate.engine.spi.CascadingActions;
2726
import org.hibernate.engine.spi.EntityEntry;
2827
import org.hibernate.engine.spi.EntityKey;
@@ -39,7 +38,6 @@
3938
import org.hibernate.jpa.event.spi.CallbackRegistry;
4039
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
4140
import org.hibernate.jpa.event.spi.CallbackType;
42-
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
4341
import org.hibernate.persister.collection.CollectionPersister;
4442
import org.hibernate.persister.entity.EntityPersister;
4543
import org.hibernate.pretty.MessageHelper;
@@ -129,17 +127,16 @@ && canBeDeletedWithoutLoading( source, persister ) ) {
129127
}
130128

131129
private static void deleteOwnedCollections(Type type, Object key, EventSource session) {
132-
final MappingMetamodelImplementor mappingMetamodel = session.getFactory().getMappingMetamodel();
133-
final ActionQueue actionQueue = session.getActionQueue();
134-
if ( type instanceof CollectionType ) {
135-
final String role = ( (CollectionType) type ).getRole();
136-
final CollectionPersister persister = mappingMetamodel.getCollectionDescriptor(role);
130+
if ( type instanceof CollectionType collectionType ) {
131+
final CollectionPersister persister =
132+
session.getFactory().getMappingMetamodel()
133+
.getCollectionDescriptor( collectionType.getRole() );
137134
if ( !persister.isInverse() && !skipRemoval( session, persister, key ) ) {
138-
actionQueue.addAction( new CollectionRemoveAction( persister, key, session ) );
135+
session.getActionQueue().addAction( new CollectionRemoveAction( persister, key, session ) );
139136
}
140137
}
141-
else if ( type instanceof ComponentType ) {
142-
final Type[] subtypes = ( (ComponentType) type ).getSubtypes();
138+
else if ( type instanceof ComponentType componentType ) {
139+
final Type[] subtypes = componentType.getSubtypes();
143140
for ( Type subtype : subtypes ) {
144141
deleteOwnedCollections( subtype, key, session );
145142
}
@@ -170,14 +167,14 @@ private void deleteUnmanagedInstance(DeleteEvent event, DeleteContext transientE
170167
}
171168
}
172169

173-
private void deleteDetachedEntity(DeleteEvent event, DeleteContext transientEntities, Object entity, EntityPersister persister, EventSource source) {
170+
private void deleteDetachedEntity(
171+
DeleteEvent event, DeleteContext transientEntities, Object entity, EntityPersister persister, EventSource source) {
174172
final Object id = persister.getIdentifier( entity, source );
175173
if ( id == null ) {
176174
throw new TransientObjectException( "Cannot delete instance of entity '"
177175
+ persister.getEntityName() + "' because it has a null identifier" );
178176
}
179177

180-
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
181178
final EntityKey key = source.generateEntityKey( id, persister);
182179
final Object version = persister.getVersion(entity);
183180

@@ -186,6 +183,7 @@ private void deleteDetachedEntity(DeleteEvent event, DeleteContext transientEnti
186183

187184
new OnUpdateVisitor( source, id, entity ).process( entity, persister );
188185

186+
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
189187
final EntityEntry entityEntry = persistenceContext.addEntity(
190188
entity,
191189
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
@@ -218,7 +216,8 @@ private static void flushAndEvictExistingEntity(
218216
source.evict( existingEntity );
219217
}
220218
else {
221-
throw new NonUniqueObjectException( key.getIdentifier(), key.getEntityName() );
219+
throw new StaleObjectStateException( key.getEntityName(), key.getIdentifier(),
220+
"Persistence context contains a more recent version of the given entity" );
222221
}
223222
}
224223
}
@@ -441,7 +440,7 @@ private Object[] createDeletedState(
441440
final Type[] types = persister.getPropertyTypes();
442441
final Object[] deletedState = new Object[types.length];
443442
if ( !persister.hasCollections() || !persister.hasUninitializedLazyProperties( parent ) ) {
444-
boolean[] copyability = new boolean[types.length];
443+
final boolean[] copyability = new boolean[types.length];
445444
java.util.Arrays.fill( copyability, true );
446445
TypeHelper.deepCopy( currentState, types, copyability, deletedState, eventSource );
447446
return deletedState;
@@ -450,10 +449,11 @@ private Object[] createDeletedState(
450449
final String[] propertyNames = persister.getPropertyNames();
451450
final BytecodeEnhancementMetadata enhancementMetadata = persister.getBytecodeEnhancementMetadata();
452451
for ( int i = 0; i < types.length; i++) {
453-
if ( types[i] instanceof CollectionType && !enhancementMetadata.isAttributeLoaded( parent, propertyNames[i] ) ) {
454-
final CollectionType collectionType = (CollectionType) types[i];
455-
final CollectionPersister collectionDescriptor = persister.getFactory().getMappingMetamodel()
456-
.getCollectionDescriptor( collectionType.getRole() );
452+
if ( types[i] instanceof CollectionType collectionType
453+
&& !enhancementMetadata.isAttributeLoaded( parent, propertyNames[i] ) ) {
454+
final CollectionPersister collectionDescriptor =
455+
persister.getFactory().getMappingMetamodel()
456+
.getCollectionDescriptor( collectionType.getRole() );
457457
if ( collectionDescriptor.needsRemove() || collectionDescriptor.hasCache() ) {
458458
final Object keyOfOwner = collectionType.getKeyOfOwner( parent, eventSource.getSession() );
459459
// This will make sure that a CollectionEntry exists
@@ -491,7 +491,7 @@ protected void cascadeBeforeDelete(
491491
Object entity,
492492
DeleteContext transientEntities) throws HibernateException {
493493

494-
CacheMode cacheMode = session.getCacheMode();
494+
final CacheMode cacheMode = session.getCacheMode();
495495
session.setCacheMode( CacheMode.GET );
496496
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
497497
persistenceContext.incrementCascadeLevel();
@@ -518,7 +518,7 @@ protected void cascadeAfterDelete(
518518
Object entity,
519519
DeleteContext transientEntities) throws HibernateException {
520520

521-
CacheMode cacheMode = session.getCacheMode();
521+
final CacheMode cacheMode = session.getCacheMode();
522522
session.setCacheMode( CacheMode.GET );
523523
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
524524
persistenceContext.incrementCascadeLevel();

hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityInitializerImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,8 @@ private void checkVersion(
11751175
if ( statistics.isStatisticsEnabled() ) {
11761176
statistics.optimisticFailure( data.concreteDescriptor.getEntityName() );
11771177
}
1178-
throw new StaleObjectStateException( data.concreteDescriptor.getEntityName(), entry.getId() );
1178+
throw new StaleObjectStateException( data.concreteDescriptor.getEntityName(), entry.getId(),
1179+
"Query result contains conflicting version of entity already held in persistence context" );
11791180
}
11801181
}
11811182

0 commit comments

Comments
 (0)