HHH-11356 - Adjust the 2nd-Cache SPIs to better reflect supported uses

- Fix-ups from Radim's review
- Better Javadoc
This commit is contained in:
Steve Ebersole 2018-03-28 11:09:04 -05:00
parent b87be0cc25
commit 9d958291d8
6 changed files with 107 additions and 73 deletions

View File

@ -62,15 +62,16 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
spacesList.addAll( Arrays.asList( (String[]) persister.getQuerySpaces() ) );
if ( persister.canWriteToCache() ) {
final EntityDataAccess entityDataAccess = factory.getCache()
.getEntityRegionAccess( persister.getNavigableRole() );
final EntityDataAccess entityDataAccess = persister.getCacheAccessStrategy();
if ( entityDataAccess != null ) {
entityCleanups.add( new EntityCleanup( entityDataAccess ) );
entityCleanups.add( new EntityCleanup( entityDataAccess, session ) );
}
}
if ( persister.hasNaturalIdentifier() && persister.hasNaturalIdCache() ) {
naturalIdCleanups.add( new NaturalIdCleanup( factory.getCache().getNaturalIdCacheRegionAccessStrategy( persister.getNavigableRole() ) ) );
naturalIdCleanups.add(
new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session )
);
}
final Set<String> roles = factory.getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() );
@ -78,7 +79,12 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
for ( String role : roles ) {
final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role );
if ( collectionPersister.hasCache() ) {
collectionCleanups.add( new CollectionCleanup( factory.getCache().getCollectionRegionAccess( collectionPersister.getNavigableRole() ) ) );
collectionCleanups.add(
new CollectionCleanup(
collectionPersister.getCacheAccessStrategy(),
session
)
);
}
}
}
@ -111,10 +117,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
spacesList.addAll( Arrays.asList( entitySpaces ) );
if ( persister.canWriteToCache() ) {
entityCleanups.add( new EntityCleanup( persister.getCacheAccessStrategy() ) );
entityCleanups.add( new EntityCleanup( persister.getCacheAccessStrategy(), session ) );
}
if ( persister.hasNaturalIdentifier() && persister.hasNaturalIdCache() ) {
naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy() ) );
naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session ) );
}
final Set<String> roles = session.getFactory().getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() );
@ -123,7 +129,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role );
if ( collectionPersister.hasCache() ) {
collectionCleanups.add(
new CollectionCleanup( collectionPersister.getCacheAccessStrategy() )
new CollectionCleanup( collectionPersister.getCacheAccessStrategy(), session )
);
}
}
@ -208,10 +214,12 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
private final EntityDataAccess cacheAccess;
private final SoftLock cacheLock;
private EntityCleanup(EntityDataAccess cacheAccess) {
private EntityCleanup(
EntityDataAccess cacheAccess,
SharedSessionContractImplementor session) {
this.cacheAccess = cacheAccess;
this.cacheLock = cacheAccess.lockRegion();
cacheAccess.removeAll();
cacheAccess.removeAll( session );
}
private void release() {
@ -223,10 +231,12 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
private final CollectionDataAccess cacheAccess;
private final SoftLock cacheLock;
private CollectionCleanup(CollectionDataAccess cacheAccess) {
private CollectionCleanup(
CollectionDataAccess cacheAccess,
SharedSessionContractImplementor session) {
this.cacheAccess = cacheAccess;
this.cacheLock = cacheAccess.lockRegion();
cacheAccess.removeAll();
cacheAccess.removeAll( session );
}
private void release() {
@ -238,10 +248,12 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
private final NaturalIdDataAccess naturalIdCacheAccessStrategy;
private final SoftLock cacheLock;
public NaturalIdCleanup(NaturalIdDataAccess naturalIdCacheAccessStrategy) {
public NaturalIdCleanup(
NaturalIdDataAccess naturalIdCacheAccessStrategy,
SharedSessionContractImplementor session) {
this.naturalIdCacheAccessStrategy = naturalIdCacheAccessStrategy;
this.cacheLock = naturalIdCacheAccessStrategy.lockRegion();
naturalIdCacheAccessStrategy.removeAll();
naturalIdCacheAccessStrategy.removeAll( session );
}
private void release() {

View File

@ -12,14 +12,19 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
* Specialized Region whose data is accessed directly (not requiring
* key/item wrapping, e.g.
*
* Does not define a "remove" operation because Hibernate's query and timestamps
* caches only ever "get" and "put"
*
* @author Steve Ebersole
*/
public interface DirectAccessRegion extends Region {
boolean contains(Object key);
/**
* Get value by key
*/
Object getFromCache(Object key, SharedSessionContractImplementor session);
/**
* Put a value by key
*/
void putIntoCache(Object key, Object value, SharedSessionContractImplementor session);
void removeFromCache(Object key, SharedSessionContractImplementor session);
}

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.cache.spi.access;
import java.io.Serializable;
import javax.persistence.Cache;
@ -18,27 +17,33 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
* Base contract for accessing the underlying cached data for a particular
* Navigable of the user's domain model in a transactionally ACID manner.
*
* @apiNote Note that the following methods are not considered "transactional"
* in this sense : {@link #contains}, {@link #lockRegion}, {@link #unlockRegion},
* {@link #evict}, {@link #evictAll}. The semantics of these methods come
* from JPA's {@link Cache} contract.
*
* @implSpec The "non transactional" methods noted in the `@apiNote` should
* be implemented to ignore any locking. In other words, if {@link #evict}
* is called that item should be forcibly removed from the cache regardless of
* whether anything has locked it.
*
* @author Steve Ebersole
* @author Gail Badner
*/
public interface CachedDomainDataAccess {
/**
* The region containing the data being accessed
*/
DomainDataRegion getRegion();
/**
* The type of access implemented
*/
AccessType getAccessType();
/**
* Determine whether this region contains data for the given key.
* <p/>
* The semantic here is whether the cache contains data visible for the
* current call context. This should be viewed as a "best effort", meaning
* blocking should be avoid if possible.
*
* @param key The cache key
*
* @return True if the underlying cache contains corresponding data; false
* otherwise.
*/
boolean contains(Object key);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Transactional
/**
* Attempt to retrieve an object from the cache. Mainly used in attempting
@ -110,15 +115,6 @@ public interface CachedDomainDataAccess {
*/
SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version);
/**
* Lock the entire region
*
* @return A representation of our lock on the item; or {@code null}.
*
* @throws CacheException Propagated from underlying cache provider
*/
SoftLock lockRegion();
/**
* Called when we have finished the attempted update/delete (which may or
* may not have been successful), after transaction completion. This method
@ -132,16 +128,6 @@ public interface CachedDomainDataAccess {
*/
void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock);
/**
* Called after we have finished the attempted invalidation of the entire
* region
*
* @param lock The lock previously obtained from {@link #lockRegion}
*
* @throws CacheException Propagated from underlying cache provider
*/
void unlockRegion(SoftLock lock);
/**
* Called afterQuery an item has become stale (beforeQuery the transaction completes).
* This method is used by "synchronous" concurrency strategies.
@ -154,11 +140,50 @@ public interface CachedDomainDataAccess {
void remove(SharedSessionContractImplementor session, Object key);
/**
* Called to evict data from the entire region
* Remove all data for this accessed type
*
* @throws CacheException Propagated from underlying cache provider
* @param session
*/
void removeAll(SharedSessionContractImplementor session);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Non-transactional
/**
* Determine whether this region contains data for the given key.
* <p/>
* The semantic here is whether the cache contains data visible for the
* current call context. This should be viewed as a "best effort", meaning
* blocking should be avoid if possible.
*
* @param key The cache key
*
* @return True if the underlying cache contains corresponding data; false
* otherwise.
*/
boolean contains(Object key);
/**
* Lock the entire region
*
* @return A representation of our lock on the item; or {@code null}.
*
* @throws CacheException Propagated from underlying cache provider
*/
void removeAll();
SoftLock lockRegion();
/**
* Called after we have finished the attempted invalidation of the entire
* region
*
* @param lock The lock previously obtained from {@link #lockRegion}
*
* @throws CacheException Propagated from underlying cache provider
*/
void unlockRegion(SoftLock lock);
/**
* Forcibly evict an item from the cache immediately without regard for transaction

View File

@ -93,8 +93,8 @@ public abstract class AbstractCachedDomainDataAccess implements CachedDomainData
}
@Override
public void removeAll() {
clearCache();
public void removeAll(SharedSessionContractImplementor session) {
getStorageAccess().clearCache( session );
}
@Override

View File

@ -27,11 +27,6 @@ public abstract class DirectAccessRegionTemplate extends AbstractRegion implemen
return storageAccess;
}
@Override
public boolean contains(Object key) {
return getStorageAccess().contains( key );
}
@Override
public Object getFromCache(Object key, SharedSessionContractImplementor session) {
return getStorageAccess().getFromCache( key, session );
@ -42,11 +37,6 @@ public abstract class DirectAccessRegionTemplate extends AbstractRegion implemen
getStorageAccess().putIntoCache( key, value, session );
}
@Override
public void removeFromCache(Object key, SharedSessionContractImplementor session) {
getStorageAccess().removeFromCache( key, session );
}
@Override
public void clear() {
getStorageAccess().evictData();

View File

@ -10,16 +10,14 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* A general read/write abstraction over the specific "cache"
* object from the caching provider
* object from the caching provider.
*
* @apiNote Similar to {@link org.hibernate.cache.spi.access.CachedDomainDataAccess},
* some methods represent "transactional" (access to Session) and some are non-"transactional"
*
* @author Steve Ebersole
*/
public interface StorageAccess {
/**
* Does the cache contain this key?
*/
boolean contains(Object key);
/**
* Get an item from the cache.
*/
@ -44,6 +42,11 @@ public interface StorageAccess {
evictData();
}
/**
* Does the cache contain this key?
*/
boolean contains(Object key);
/**
* Clear all data regardless of transaction/locking
*/
@ -54,9 +57,8 @@ public interface StorageAccess {
*/
void evictData(Object key);
/***
/**
* Release any resources. Called during cache shutdown
*/
void release();
}