org.hibernate.cache.spi.access.EntityDataAccess Java Examples

The following examples show how to use org.hibernate.cache.spi.access.EntityDataAccess. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AbstractDomainDataRegion.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private Map<NavigableRole, EntityDataAccess> generateEntityDataAccessMap(
		DomainDataRegionConfig regionConfig) {
	if ( regionConfig.getEntityCaching().isEmpty() ) {
		return Collections.emptyMap();
	}

	final Map<NavigableRole, EntityDataAccess> accessMap = new ConcurrentHashMap<>();
	for ( EntityDataCachingConfig entityAccessConfig : regionConfig.getEntityCaching() ) {
		accessMap.computeIfAbsent(
				entityAccessConfig.getNavigableRole(),
				hierarchy -> generateEntityAccess( entityAccessConfig )
		);
	}

	return Collections.unmodifiableMap( accessMap );
}
 
Example #2
Source File: DomainDataRegionTemplate.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public EntityDataAccess generateEntityAccess(EntityDataCachingConfig entityAccessConfig) {
	final NavigableRole namedEntityRole = entityAccessConfig.getNavigableRole();
	final AccessType accessType = entityAccessConfig.getAccessType();

	log.debugf( "Generating entity cache access [%s] : %s", accessType.getExternalName(), namedEntityRole );

	switch ( accessType ) {
		case READ_ONLY: {
			return generateReadOnlyEntityAccess( entityAccessConfig );
		}
		case READ_WRITE: {
			return generateReadWriteEntityAccess( entityAccessConfig );
		}
		case NONSTRICT_READ_WRITE: {
			return generateNonStrictReadWriteEntityAccess( entityAccessConfig );
		}
		case TRANSACTIONAL: {
			return generateTransactionalEntityDataAccess( entityAccessConfig );
		}
		default: {
			throw new IllegalArgumentException( "Unrecognized cache AccessType - " + accessType );
		}
	}
}
 
Example #3
Source File: EnabledCaching.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void evictEntityData(String entityName, Serializable identifier) {
	final EntityPersister entityDescriptor = sessionFactory.getMetamodel().entityPersister( entityName );
	final EntityDataAccess cacheAccess = entityDescriptor.getCacheAccessStrategy();
	if ( cacheAccess == null ) {
		return;
	}

	if ( LOG.isDebugEnabled() ) {
		LOG.debugf(
				"Evicting second-level cache: %s",
				MessageHelper.infoString( entityDescriptor, identifier, sessionFactory )
		);
	}

	final Object key = cacheAccess.generateCacheKey( identifier, entityDescriptor, sessionFactory, null );
	cacheAccess.evict( key );
}
 
Example #4
Source File: EntityInsertAction.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) throws HibernateException {
	final EntityPersister persister = getPersister();
	if ( success && isCachePutEnabled( persister, getSession() ) ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		SessionFactoryImplementor factory = session.getFactory();
		final Object ck = cache.generateCacheKey( getId(), persister, factory, session.getTenantIdentifier() );
		final boolean put = cacheAfterInsert( cache, ck );

		if ( put && factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatistics().entityCachePut(
					StatsHelper.INSTANCE.getRootEntityRole( persister ),
					cache.getRegion().getName()
			);
		}
	}
	postCommitInsert( success );
}
 
Example #5
Source File: PersisterFactoryImpl.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
@SuppressWarnings( {"unchecked"})
public EntityPersister createEntityPersister(
		PersistentClass entityBinding,
		EntityDataAccess entityCacheAccessStrategy,
		NaturalIdDataAccess naturalIdCacheAccessStrategy,
		PersisterCreationContext creationContext) throws HibernateException {
	// If the metadata for the entity specified an explicit persister class, use it...
	Class<? extends EntityPersister> persisterClass = entityBinding.getEntityPersisterClass();
	if ( persisterClass == null ) {
		// Otherwise, use the persister class indicated by the PersisterClassResolver service
		persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( entityBinding );
	}

	return createEntityPersister(
			persisterClass,
			entityBinding,
			entityCacheAccessStrategy,
			naturalIdCacheAccessStrategy,
			creationContext
	);
}
 
Example #6
Source File: AbstractEntityPersister.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@SuppressWarnings("unchecked")
private boolean determineCanReadFromCache(PersistentClass persistentClass, EntityDataAccess cacheAccessStrategy) {
	if ( cacheAccessStrategy == null ) {
		return false;
	}

	if ( persistentClass.isCached() ) {
		return true;
	}

	final Iterator<Subclass> subclassIterator = persistentClass.getSubclassIterator();
	while ( subclassIterator.hasNext() ) {
		final Subclass subclass = subclassIterator.next();
		if ( subclass.isCached() ) {
			return true;
		}
	}
	return false;
}
 
Example #7
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private Object getFromSharedCache(
	final LoadEvent event,
	final EntityPersister persister,
	SessionImplementor source ) {
	final EntityDataAccess cache = persister.getCacheAccessStrategy();
	final Object ck = cache.generateCacheKey(
			event.getEntityId(),
			persister,
			source.getFactory(),
			source.getTenantIdentifier()
	);

	final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() );
	if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
		if ( ce == null ) {
			source.getFactory().getStatistics().entityCacheMiss(
					StatsHelper.INSTANCE.getRootEntityRole( persister ),
					cache.getRegion().getName()
			);
		}
		else {
			source.getFactory().getStatistics().entityCacheHit(
					StatsHelper.INSTANCE.getRootEntityRole( persister ),
					cache.getRegion().getName()
			);
		}
	}
	return ce;
}
 
Example #8
Source File: AbstractDomainDataRegion.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public EntityDataAccess getEntityDataAccess(NavigableRole rootEntityRole) {
	final EntityDataAccess access = entityDataAccessMap.get( rootEntityRole );
	if ( access == null ) {
		throw new IllegalArgumentException( "Caching was not configured for entity : " + rootEntityRole.getFullPath() );
	}
	return access;
}
 
Example #9
Source File: DomainDataRegionImpl.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
protected EntityDataAccess generateTransactionalEntityDataAccess(EntityDataCachingConfig entityAccessConfig) {
	return new EntityTransactionalAccess(
			this,
			getEffectiveKeysFactory(),
			getCacheStorageAccess(),
			entityAccessConfig
	);
}
 
Example #10
Source File: EnabledCaching.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean containsEntity(String entityName, Serializable identifier) {
	final EntityPersister entityDescriptor = sessionFactory.getMetamodel().entityPersister( entityName );
	final EntityDataAccess cacheAccess = entityDescriptor.getCacheAccessStrategy();
	if ( cacheAccess == null ) {
		return false;
	}

	final Object key = cacheAccess.generateCacheKey( identifier, entityDescriptor, sessionFactory, null );
	return cacheAccess.contains( key );
}
 
Example #11
Source File: EnabledCaching.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void evictEntityData(NavigableRole navigableRole, EntityDataAccess cacheAccess) {
	if ( cacheAccess == null ) {
		return;
	}

	if ( LOG.isDebugEnabled() ) {
		LOG.debugf( "Evicting entity cache: %s", navigableRole.getFullPath() );
	}

	cacheAccess.evictAll();
}
 
Example #12
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * If the class to be loaded has been configured with a cache, then lock
 * given id in that cache and then perform the load.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param source The originating session
 *
 * @return The loaded entity
 *
 * @throws HibernateException
 */
private Object lockAndLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final SessionImplementor source) {
	SoftLock lock = null;
	final Object ck;
	final EntityDataAccess cache = persister.getCacheAccessStrategy();
	if ( persister.canWriteToCache() ) {
		ck = cache.generateCacheKey(
				event.getEntityId(),
				persister,
				source.getFactory(),
				source.getTenantIdentifier()
		);
		lock = persister.getCacheAccessStrategy().lockItem( source, ck, null );
	}
	else {
		ck = null;
	}

	Object entity;
	try {
		entity = load( event, persister, keyToLoad, options );
	}
	finally {
		if ( persister.canWriteToCache() ) {
			cache.unlockItem( source, ck, lock );
		}
	}

	return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
}
 
Example #13
Source File: IgniteDomainDataRegion.java    From ignite with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override protected EntityDataAccess generateEntityAccess(EntityDataCachingConfig entityAccessCfg) {
    AccessType accessType = entityAccessCfg.getAccessType();
    Ignite ignite = stgyFactory.node();
    switch (accessType) {
        case READ_ONLY:
            HibernateAccessStrategyAdapter readOnlyStgy =
                stgyFactory.createReadOnlyStrategy(cache);
            return new IgniteEntityDataAccess(readOnlyStgy, accessType, getRegionFactory(),
                this, ignite, cache);

        case NONSTRICT_READ_WRITE:
            HibernateAccessStrategyAdapter nonStrictReadWriteStgy =
                stgyFactory.createNonStrictReadWriteStrategy(cache);
            return new IgniteEntityDataAccess(nonStrictReadWriteStgy, accessType, getRegionFactory(),
                this, ignite, cache);

        case READ_WRITE:
            HibernateAccessStrategyAdapter readWriteStgy =
                stgyFactory.createReadWriteStrategy(cache);
            return new IgniteEntityDataAccess(readWriteStgy, accessType, getRegionFactory(),
                this, ignite, cache);

        case TRANSACTIONAL:
            HibernateAccessStrategyAdapter transactionalStgy =
                stgyFactory.createTransactionalStrategy(cache);
            return new IgniteEntityDataAccess(transactionalStgy, accessType, getRegionFactory(),
                this, ignite, cache);

        default:
            throw new IllegalArgumentException("Unknown Hibernate access type: " + accessType);
    }
}
 
Example #14
Source File: EntityDeleteAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) throws HibernateException {
	EntityPersister entityPersister = getPersister();
	if ( entityPersister.canWriteToCache() ) {
		EntityDataAccess cache = entityPersister.getCacheAccessStrategy();
		final Object ck = cache.generateCacheKey(
				getId(),
				entityPersister,
				session.getFactory(),
				session.getTenantIdentifier()
		);
		cache.unlockItem( session, ck, lock );
	}
	postCommitDelete( success );
}
 
Example #15
Source File: EntityInsertAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private boolean cacheAfterInsert(EntityDataAccess cache, Object ck) {
	SharedSessionContractImplementor session = getSession();
	final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
	try {
		eventListenerManager.cachePutStart();
		return cache.afterInsert( session, ck, cacheEntry, version );
	}
	finally {
		eventListenerManager.cachePutEnd();
	}
}
 
Example #16
Source File: BulkOperationCleanupAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Constructs an action to cleanup "affected cache regions" based on the
 * affected entity persisters.  The affected regions are defined as the
 * region (if any) of the entity persisters themselves, plus the
 * collection regions for any collection in which those entity
 * persisters participate as elements/keys/etc.
 *
 * @param session The session to which this request is tied.
 * @param affectedQueryables The affected entity persisters.
 */
public BulkOperationCleanupAction(SharedSessionContractImplementor session, Queryable... affectedQueryables) {
	final SessionFactoryImplementor factory = session.getFactory();
	final LinkedHashSet<String> spacesList = new LinkedHashSet<>();
	for ( Queryable persister : affectedQueryables ) {
		spacesList.addAll( Arrays.asList( (String[]) persister.getQuerySpaces() ) );

		if ( persister.canWriteToCache() ) {
			final EntityDataAccess entityDataAccess = persister.getCacheAccessStrategy();
			if ( entityDataAccess != null ) {
				entityCleanups.add( new EntityCleanup( entityDataAccess, session ) );
			}
		}

		if ( persister.hasNaturalIdentifier() && persister.hasNaturalIdCache() ) {
			naturalIdCleanups.add(
					new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session )
			);
		}

		final Set<String> roles = factory.getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() );
		if ( roles != null ) {
			for ( String role : roles ) {
				final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role );
				if ( collectionPersister.hasCache() ) {
					collectionCleanups.add(
							new CollectionCleanup(
									collectionPersister.getCacheAccessStrategy(),
									session
							)
					);
				}
			}
		}
	}

	this.affectedTableSpaces = spacesList.toArray( new String[ spacesList.size() ] );
}
 
Example #17
Source File: BulkOperationCleanupAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private EntityCleanup(
		EntityDataAccess cacheAccess,
		SharedSessionContractImplementor session) {
	this.cacheAccess = cacheAccess;
	this.cacheLock = cacheAccess.lockRegion();
	cacheAccess.removeAll( session );
}
 
Example #18
Source File: EntityUpdateAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) throws CacheException {
	final EntityPersister persister = getPersister();
	if ( persister.canWriteToCache() ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		final Object ck = cache.generateCacheKey(
				getId(),
				persister,
				session.getFactory(),
				session.getTenantIdentifier()
				
		);

		if ( success &&
				cacheEntry != null &&
				!persister.isCacheInvalidationRequired() &&
				session.getCacheMode().isPutEnabled() ) {
			final boolean put = cacheAfterUpdate( cache, ck );

			if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
				session.getFactory().getStatistics().entityCachePut(
						StatsHelper.INSTANCE.getRootEntityRole( persister ),
						getPersister().getCacheAccessStrategy().getRegion().getName()
				);
			}
		}
		else {
			cache.unlockItem(session, ck, lock );
		}
	}
	postCommitUpdate( success );
}
 
Example #19
Source File: EntityUpdateAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private boolean cacheAfterUpdate(EntityDataAccess cache, Object ck) {
	final SharedSessionContractImplementor session = getSession();
	SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
	try {
		eventListenerManager.cachePutStart();
		return cache.afterUpdate( session, ck, cacheEntry, nextVersion, previousVersion, lock );
	}
	finally {
		eventListenerManager.cachePutEnd();
	}
}
 
Example #20
Source File: ReactiveSingleTableEntityPersister.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
public ReactiveSingleTableEntityPersister(
		PersistentClass persistentClass,
		EntityDataAccess cacheAccessStrategy,
		NaturalIdDataAccess naturalIdRegionAccessStrategy,
		PersisterCreationContext creationContext) throws HibernateException {
	super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
}
 
Example #21
Source File: ReactiveJoinedSubclassEntityPersister.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
public ReactiveJoinedSubclassEntityPersister(
		PersistentClass persistentClass,
		EntityDataAccess cacheAccessStrategy,
		NaturalIdDataAccess naturalIdRegionAccessStrategy,
		PersisterCreationContext creationContext) throws HibernateException {
	super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
}
 
Example #22
Source File: DomainDataRegionTemplate.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@SuppressWarnings("WeakerAccess")
protected EntityDataAccess generateReadWriteEntityAccess(EntityDataCachingConfig accessConfig) {
	return new EntityReadWriteAccess(
			this,
			getEffectiveKeysFactory(),
			getCacheStorageAccess(),
			accessConfig
	);
}
 
Example #23
Source File: ReactiveUnionSubclassEntityPersister.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
public ReactiveUnionSubclassEntityPersister(
		PersistentClass persistentClass,
		EntityDataAccess cacheAccessStrategy,
		NaturalIdDataAccess naturalIdRegionAccessStrategy,
		PersisterCreationContext creationContext) throws HibernateException {
	super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
}
 
Example #24
Source File: DomainDataRegionTemplate.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@SuppressWarnings("WeakerAccess")
protected EntityDataAccess generateReadOnlyEntityAccess(EntityDataCachingConfig accessConfig) {
	return new EntityReadOnlyAccess(
			this,
			getEffectiveKeysFactory(),
			getCacheStorageAccess(),
			accessConfig
	);
}
 
Example #25
Source File: AbstractEntityPersister.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private boolean determineCanWriteToCache(PersistentClass persistentClass, EntityDataAccess cacheAccessStrategy) {
	if ( cacheAccessStrategy == null ) {
		return false;
	}

	return persistentClass.isCached();
}
 
Example #26
Source File: BatchFetchQueue.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private boolean isCached(EntityKey entityKey, EntityPersister persister) {
	final SharedSessionContractImplementor session = context.getSession();
	if ( context.getSession().getCacheMode().isGetEnabled() && persister.canReadFromCache() ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		final Object key = cache.generateCacheKey(
				entityKey.getIdentifier(),
				persister,
				session.getFactory(),
				session.getTenantIdentifier()
		);
		return CacheHelper.fromSharedCache( session, key, cache ) != null;
	}
	return false;
}
 
Example #27
Source File: DomainDataRegionTemplate.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@SuppressWarnings("WeakerAccess")
protected EntityDataAccess generateNonStrictReadWriteEntityAccess(EntityDataCachingConfig accessConfig) {
	return new EntityNonStrictReadWriteAccess(
			this,
			getEffectiveKeysFactory(),
			getCacheStorageAccess(),
			accessConfig
	);
}
 
Example #28
Source File: EnabledCaching.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public EntityDataAccess getEntityRegionAccess(NavigableRole rootEntityName) {
	return entityAccessMap.get( rootEntityName );
}
 
Example #29
Source File: ReactiveEntityRegularInsertAction.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public CompletionStage<Void> reactiveExecute() throws HibernateException {

	return reactiveNullifyTransientReferencesIfNotAlready().thenCompose( v-> {

		EntityPersister persister = getPersister();
		final SharedSessionContractImplementor session = getSession();
		final Object instance = getInstance();
		final Serializable id = getId();

		// FIXME: It needs to become async
		final boolean veto = preInsert();

		// Don't need to lock the cache here, since if someone
		// else inserted the same pk first, the insert would fail
		CompletionStage<Void> insertStage;
		if ( !veto ) {
			insertStage = ((ReactiveEntityPersister) persister)
					.insertReactive( id, getState(), instance, session )
					.thenApply( res -> {
						PersistenceContext persistenceContext = session.getPersistenceContext();
						final EntityEntry entry = persistenceContext.getEntry( instance );
						if ( entry == null ) {
							throw new AssertionFailure( "possible non-threadsafe access to session" );
						}

						entry.postInsert( getState() );

						if ( persister.hasInsertGeneratedProperties() ) {
							persister.processInsertGeneratedProperties( id, instance, getState(), session );
							if ( persister.isVersionPropertyGenerated() ) {
								setVersion( Versioning.getVersion( getState(), persister ) );
							}
							entry.postUpdate( instance, getState(), getVersion() );
						}

						persistenceContext.registerInsertedKey( persister, getId() );
						return null;
					} );
		}
		else {
			insertStage = CompletionStages.nullFuture();
		}

		return insertStage.thenApply( res -> {
			final SessionFactoryImplementor factory = session.getFactory();

			if ( isCachePutEnabled( persister, session ) ) {
				final CacheEntry ce = persister.buildCacheEntry(
						instance,
						getState(),
						getVersion(),
						session
				);
				setCacheEntry( persister.getCacheEntryStructure().structure( ce ) );
				final EntityDataAccess cache = persister.getCacheAccessStrategy();
				final Object ck = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() );

				final boolean put = cacheInsert( persister, ck );

				if ( put && factory.getStatistics().isStatisticsEnabled() ) {
					factory.getStatistics().entityCachePut(
							persister.getNavigableRole(),
							persister.getCacheAccessStrategy().getRegion().getName()
					);
				}
			}

			handleNaturalIdPostSaveNotifications( id );

			postInsert();

			if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
				factory.getStatistics().insertEntity( getEntityName() );
			}

			markExecuted();
			return null;
		} );
	} );
}
 
Example #30
Source File: ReactiveEntityDeleteAction.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public CompletionStage<Void> reactiveExecute() throws HibernateException {
	final Serializable id = getId();
	final EntityPersister persister = getPersister();
	final SharedSessionContractImplementor session = getSession();
	final Object instance = getInstance();

	final boolean veto = preDelete();

	Object version = getVersion();
	if ( persister.isVersionPropertyGenerated() ) {
		// we need to grab the version value from the entity, otherwise
		// we have issues with generated-version entities that may have
		// multiple actions queued during the same flush
		version = persister.getVersion( instance );
	}

	final Object ck;
	if ( persister.canWriteToCache() ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		ck = cache.generateCacheKey( id, persister, session.getFactory(), session.getTenantIdentifier() );
		setLock( cache.lockItem( session, ck, version ) );
	}
	else {
		ck = null;
	}

	CompletionStage<?> deleteStep = CompletionStages.nullFuture();
	if ( !isCascadeDeleteEnabled() && !veto ) {
		deleteStep = ((ReactiveEntityPersister) persister).deleteReactive( id, version, instance, session );
	}

	return deleteStep.thenAccept( deleteAR -> {
		//postDelete:
		// After actually deleting a row, record the fact that the instance no longer
		// exists on the database (needed for identity-column key generation), and
		// remove it from the session cache
		final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
		final EntityEntry entry = persistenceContext.removeEntry( instance );
		if ( entry == null ) {
			throw new AssertionFailure( "possible non-threadsafe access to session" );
		}
		entry.postDelete();

		persistenceContext.removeEntity( entry.getEntityKey() );
		persistenceContext.removeProxy( entry.getEntityKey() );

		if ( persister.canWriteToCache() ) {
			persister.getCacheAccessStrategy().remove( session, ck );
		}

		persistenceContext.getNaturalIdHelper().removeSharedNaturalIdCrossReference(
				persister,
				id,
				getNaturalIdValues()
		);

		postDelete();

		final StatisticsImplementor statistics = getSession().getFactory().getStatistics();
		if ( statistics.isStatisticsEnabled() && !veto ) {
			statistics.deleteEntity( getPersister().getEntityName() );
		}
	} );
}