HHH-16557 Testcase and bugfix proposal (revised by beikov)
This commit is contained in:
parent
f9f540b848
commit
53398df5f3
|
@ -174,7 +174,7 @@ public class EntityDeleteAction extends EntityAction {
|
||||||
final EntityKey key = entry.getEntityKey();
|
final EntityKey key = entry.getEntityKey();
|
||||||
persistenceContext.removeEntityHolder( key );
|
persistenceContext.removeEntityHolder( key );
|
||||||
removeCacheItem( ck );
|
removeCacheItem( ck );
|
||||||
persistenceContext.getNaturalIdResolutions().removeSharedResolution( id, naturalIdValues, persister );
|
persistenceContext.getNaturalIdResolutions().removeSharedResolution( id, naturalIdValues, persister, true);
|
||||||
postDelete();
|
postDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -433,6 +433,11 @@ public class NaturalIdResolutionsImpl implements NaturalIdResolutions, Serializa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor) {
|
public void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor) {
|
||||||
|
removeSharedResolution( id, naturalId, entityDescriptor, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor, boolean delayToAfterTransactionCompletion) {
|
||||||
final NaturalIdMapping naturalIdMapping = entityDescriptor.getNaturalIdMapping();
|
final NaturalIdMapping naturalIdMapping = entityDescriptor.getNaturalIdMapping();
|
||||||
if ( naturalIdMapping == null ) {
|
if ( naturalIdMapping == null ) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
@ -453,7 +458,18 @@ public class NaturalIdResolutionsImpl implements NaturalIdResolutions, Serializa
|
||||||
final EntityPersister persister = locatePersisterForKey( entityDescriptor.getEntityPersister() );
|
final EntityPersister persister = locatePersisterForKey( entityDescriptor.getEntityPersister() );
|
||||||
|
|
||||||
final Object naturalIdCacheKey = cacheAccess.generateCacheKey( naturalId, persister, session() );
|
final Object naturalIdCacheKey = cacheAccess.generateCacheKey( naturalId, persister, session() );
|
||||||
|
if ( delayToAfterTransactionCompletion ) {
|
||||||
|
session().asEventSource().getActionQueue().registerProcess(
|
||||||
|
(success, session) -> {
|
||||||
|
if ( success ) {
|
||||||
cacheAccess.evict( naturalIdCacheKey );
|
cacheAccess.evict( naturalIdCacheKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cacheAccess.evict( naturalIdCacheKey );
|
||||||
|
}
|
||||||
|
|
||||||
// if ( sessionCachedNaturalIdValues != null
|
// if ( sessionCachedNaturalIdValues != null
|
||||||
// && !Arrays.equals( sessionCachedNaturalIdValues, deletedNaturalIdValues ) ) {
|
// && !Arrays.equals( sessionCachedNaturalIdValues, deletedNaturalIdValues ) ) {
|
||||||
|
@ -479,7 +495,7 @@ public class NaturalIdResolutionsImpl implements NaturalIdResolutions, Serializa
|
||||||
cacheResolution( pk, naturalIdValuesFromCurrentObjectState, persister );
|
cacheResolution( pk, naturalIdValuesFromCurrentObjectState, persister );
|
||||||
stashInvalidNaturalIdReference( persister, cachedNaturalIdValues );
|
stashInvalidNaturalIdReference( persister, cachedNaturalIdValues );
|
||||||
|
|
||||||
removeSharedResolution( pk, cachedNaturalIdValues, persister );
|
removeSharedResolution( pk, cachedNaturalIdValues, persister, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,11 @@ public interface NaturalIdResolutions {
|
||||||
/**
|
/**
|
||||||
* Removes any cross-reference from the L2 cache
|
* Removes any cross-reference from the L2 cache
|
||||||
*/
|
*/
|
||||||
void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor);
|
void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor, boolean delayToAfterTransactionCompletion);
|
||||||
|
|
||||||
|
default void removeSharedResolution(Object id, Object naturalId, EntityMappingType entityDescriptor) {
|
||||||
|
removeSharedResolution( id, naturalId, entityDescriptor, false );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the cached natural-id for the given identifier
|
* Find the cached natural-id for the given identifier
|
||||||
|
|
|
@ -4110,7 +4110,7 @@ public abstract class AbstractEntityPersister
|
||||||
? null
|
? null
|
||||||
: naturalIdMapping.extractNaturalIdFromEntityState( entitySnapshot );
|
: naturalIdMapping.extractNaturalIdFromEntityState( entitySnapshot );
|
||||||
|
|
||||||
naturalIdResolutions.removeSharedResolution( id, naturalIdSnapshot, this );
|
naturalIdResolutions.removeSharedResolution( id, naturalIdSnapshot, this, false );
|
||||||
final Object naturalId = naturalIdMapping.extractNaturalIdFromEntity( entity );
|
final Object naturalId = naturalIdMapping.extractNaturalIdFromEntity( entity );
|
||||||
naturalIdResolutions.manageLocalResolution( id, naturalId, this, CachedNaturalIdValueSource.UPDATE );
|
naturalIdResolutions.manageLocalResolution( id, naturalId, this, CachedNaturalIdValueSource.UPDATE );
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,40 @@ public abstract class CachedMutableNaturalIdTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-16557" )
|
||||||
|
public void testCreateDeleteRecreate(SessionFactoryScope scope) {
|
||||||
|
|
||||||
|
final Integer id = scope.fromTransaction(
|
||||||
|
(session) -> {
|
||||||
|
AllCached it = new AllCached( "it" );
|
||||||
|
session.persist(it);
|
||||||
|
session.remove(it);
|
||||||
|
// insert-remove might happen in an app driven by users GUI interactions
|
||||||
|
return it.getId();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// now recreate with same naturalId value
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
AllCached it = new AllCached( "it" );
|
||||||
|
session.persist(it);
|
||||||
|
// resolving from first level cache
|
||||||
|
assertNotNull(session.bySimpleNaturalId( AllCached.class ).load( "it" ));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
// should resolve from second level cache
|
||||||
|
final AllCached shouldBeThere = session.bySimpleNaturalId( AllCached.class ).load( "it" );
|
||||||
|
assertNotNull( shouldBeThere );
|
||||||
|
assert(id.compareTo(shouldBeThere.getId()) != 0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@JiraKey("HHH-16558")
|
@JiraKey("HHH-16558")
|
||||||
public void testCacheVerifyHits(SessionFactoryScope scope) {
|
public void testCacheVerifyHits(SessionFactoryScope scope) {
|
||||||
|
|
Loading…
Reference in New Issue