Skip to content

Commit ece64c7

Browse files
pb00068beikov
authored andcommitted
HHH-16557 Testcase and bugfix proposal (revised by beikov)
1 parent f44332c commit ece64c7

File tree

5 files changed

+60
-6
lines changed

5 files changed

+60
-6
lines changed

hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ protected void postDeleteLoaded(
174174
final EntityKey key = entry.getEntityKey();
175175
persistenceContext.removeEntityHolder( key );
176176
removeCacheItem( ck );
177-
persistenceContext.getNaturalIdResolutions().removeSharedResolution( id, naturalIdValues, persister );
177+
persistenceContext.getNaturalIdResolutions().removeSharedResolution( id, naturalIdValues, persister, true);
178178
postDelete();
179179
}
180180

hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdResolutionsImpl.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,11 @@ private void manageSharedResolution(
433433

434434
@Override
435435
public void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor) {
436+
removeSharedResolution( id, naturalId, entityDescriptor, false );
437+
}
438+
439+
@Override
440+
public void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor, boolean delayToAfterTransactionCompletion) {
436441
final NaturalIdMapping naturalIdMapping = entityDescriptor.getNaturalIdMapping();
437442
if ( naturalIdMapping == null ) {
438443
// nothing to do
@@ -453,7 +458,18 @@ public void removeSharedResolution(Object id, Object naturalId, EntityMappingTyp
453458
final EntityPersister persister = locatePersisterForKey( entityDescriptor.getEntityPersister() );
454459

455460
final Object naturalIdCacheKey = cacheAccess.generateCacheKey( naturalId, persister, session() );
456-
cacheAccess.evict( naturalIdCacheKey );
461+
if ( delayToAfterTransactionCompletion ) {
462+
session().asEventSource().getActionQueue().registerProcess(
463+
(success, session) -> {
464+
if ( success ) {
465+
cacheAccess.evict( naturalIdCacheKey );
466+
}
467+
}
468+
);
469+
}
470+
else {
471+
cacheAccess.evict( naturalIdCacheKey );
472+
}
457473

458474
// if ( sessionCachedNaturalIdValues != null
459475
// && !Arrays.equals( sessionCachedNaturalIdValues, deletedNaturalIdValues ) ) {
@@ -479,7 +495,7 @@ public void handleSynchronization(Object pk, Object entity, EntityMappingType en
479495
cacheResolution( pk, naturalIdValuesFromCurrentObjectState, persister );
480496
stashInvalidNaturalIdReference( persister, cachedNaturalIdValues );
481497

482-
removeSharedResolution( pk, cachedNaturalIdValues, persister );
498+
removeSharedResolution( pk, cachedNaturalIdValues, persister, false );
483499
}
484500
}
485501

hibernate-core/src/main/java/org/hibernate/engine/spi/NaturalIdResolutions.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,12 @@ void manageSharedResolution(
6868
/**
6969
* Removes any cross-reference from the L2 cache
7070
*/
71-
void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor);
72-
71+
void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor, boolean delayToAfterTransactionCompletion);
72+
73+
default void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor) {
74+
removeSharedResolution( id, naturalId, entityDescriptor, false );
75+
}
76+
7377
/**
7478
* Find the cached natural-id for the given identifier
7579
*

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -4115,7 +4115,7 @@ private void handleNaturalIdReattachment(Object entity, SharedSessionContractImp
41154115
? null
41164116
: naturalIdMapping.extractNaturalIdFromEntityState( entitySnapshot );
41174117

4118-
naturalIdResolutions.removeSharedResolution( id, naturalIdSnapshot, this );
4118+
naturalIdResolutions.removeSharedResolution( id, naturalIdSnapshot, this, false );
41194119
final Object naturalId = naturalIdMapping.extractNaturalIdFromEntity( entity );
41204120
naturalIdResolutions.manageLocalResolution( id, naturalId, this, CachedNaturalIdValueSource.UPDATE );
41214121
}

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/mutable/cached/CachedMutableNaturalIdTest.java

+34
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,40 @@ public void testBySimpleNaturalIdResolveEntityFrom2LCacheSubClass(SessionFactory
179179
}
180180
);
181181
}
182+
183+
@Test
184+
@TestForIssue( jiraKey = "HHH-16557" )
185+
public void testCreateDeleteRecreate(SessionFactoryScope scope) {
186+
187+
final Integer id = scope.fromTransaction(
188+
(session) -> {
189+
AllCached it = new AllCached( "it" );
190+
session.persist(it);
191+
session.remove(it);
192+
// insert-remove might happen in an app driven by users GUI interactions
193+
return it.getId();
194+
}
195+
);
196+
197+
// now recreate with same naturalId value
198+
scope.inTransaction(
199+
(session) -> {
200+
AllCached it = new AllCached( "it" );
201+
session.persist(it);
202+
// resolving from first level cache
203+
assertNotNull(session.bySimpleNaturalId( AllCached.class ).load( "it" ));
204+
}
205+
);
206+
207+
scope.inTransaction(
208+
(session) -> {
209+
// should resolve from second level cache
210+
final AllCached shouldBeThere = session.bySimpleNaturalId( AllCached.class ).load( "it" );
211+
assertNotNull( shouldBeThere );
212+
assert(id.compareTo(shouldBeThere.getId()) != 0);
213+
}
214+
);
215+
}
182216

183217
@Test
184218
@JiraKey("HHH-16558")

0 commit comments

Comments
 (0)