下面列出了org.hibernate.persister.collection.CollectionPersister#hasCache ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void evictCachedCollections(Type[] types, Serializable id, EventSource source)
throws HibernateException {
for ( Type type : types ) {
if ( type.isCollectionType() ) {
CollectionPersister collectionPersister = source.getFactory().getMetamodel().collectionPersister( ( (CollectionType) type ).getRole() );
if ( collectionPersister.hasCache() ) {
final CollectionDataAccess cache = collectionPersister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(
id,
collectionPersister,
source.getFactory(),
source.getTenantIdentifier()
);
final SoftLock lock = cache.lockItem( source, ck, null );
cache.remove( source, ck );
source.getActionQueue().registerProcess( (success, session) -> cache.unlockItem( session, ck, lock ) );
}
}
else if ( type.isComponentType() ) {
CompositeType actype = (CompositeType) type;
evictCachedCollections( actype.getSubtypes(), id, source );
}
}
}
private boolean isCached(
Serializable collectionKey,
CollectionPersister persister,
EntityMode entityMode) {
if ( persister.hasCache() ) {
CacheKey cacheKey = new CacheKey(
collectionKey,
persister.getKeyType(),
persister.getRole(),
entityMode,
context.getSession().getFactory()
);
return persister.getCache().getCache().get( cacheKey ) != null;
}
return false;
}
protected static boolean isCached(
PersistenceContext context,
Serializable collectionKey,
CollectionPersister persister,
EntityMode entityMode) {
if ( persister.hasCache() ) {
CacheKey cacheKey = new CacheKey(
collectionKey,
persister.getKeyType(),
persister.getRole(),
entityMode,
context.getSession().getFactory()
);
return persister.getCacheAccessStrategy().get( cacheKey, context.getSession().getTimestamp() ) != null;
}
return false;
}
private void evictCachedCollections(Type[] types, Serializable id, EventSource source)
throws HibernateException {
final ActionQueue actionQueue = source.getActionQueue();
final SessionFactoryImplementor factory = source.getFactory();
final MetamodelImplementor metamodel = factory.getMetamodel();
for ( Type type : types ) {
if ( type.isCollectionType() ) {
CollectionPersister collectionPersister = metamodel.collectionPersister( ( (CollectionType) type ).getRole() );
if ( collectionPersister.hasCache() ) {
final CollectionDataAccess cache = collectionPersister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(
id,
collectionPersister,
factory,
source.getTenantIdentifier()
);
final SoftLock lock = cache.lockItem( source, ck, null );
cache.remove( source, ck );
actionQueue.registerProcess( (success, session) -> cache.unlockItem( session, ck, lock ) );
}
}
else if ( type.isComponentType() ) {
CompositeType actype = (CompositeType) type;
evictCachedCollections( actype.getSubtypes(), id, source );
}
}
}
private boolean isCached(Serializable collectionKey, CollectionPersister persister) {
SharedSessionContractImplementor session = context.getSession();
if ( session.getCacheMode().isGetEnabled() && persister.hasCache() ) {
CollectionDataAccess cache = persister.getCacheAccessStrategy();
Object cacheKey = cache.generateCacheKey(
collectionKey,
persister,
session.getFactory(),
session.getTenantIdentifier()
);
return CacheHelper.fromSharedCache( session, cacheKey, cache ) != null;
}
return false;
}
/**
* 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() ] );
}
/**
* Constructs an action to cleanup "affected cache regions" based on a
* set of affected table spaces. This differs from {@link #BulkOperationCleanupAction(SharedSessionContractImplementor, Queryable[])}
* in that here we have the affected <strong>table names</strong>. From those
* we deduce the entity persisters which are affected based on the defined
* {@link EntityPersister#getQuerySpaces() table spaces}; and from there, we
* determine the affected collection regions based on any collections
* in which those entity persisters participate as elements/keys/etc.
*
* @param session The session to which this request is tied.
* @param tableSpaces The table spaces.
*/
@SuppressWarnings({ "unchecked" })
public BulkOperationCleanupAction(SharedSessionContractImplementor session, Set tableSpaces) {
final LinkedHashSet<String> spacesList = new LinkedHashSet<>();
spacesList.addAll( tableSpaces );
final SessionFactoryImplementor factory = session.getFactory();
for ( EntityPersister persister : factory.getMetamodel().entityPersisters().values() ) {
final String[] entitySpaces = (String[]) persister.getQuerySpaces();
if ( affectedEntity( tableSpaces, entitySpaces ) ) {
spacesList.addAll( Arrays.asList( entitySpaces ) );
if ( persister.canWriteToCache() ) {
entityCleanups.add( new EntityCleanup( persister.getCacheAccessStrategy(), session ) );
}
if ( persister.hasNaturalIdentifier() && persister.hasNaturalIdCache() ) {
naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session ) );
}
final Set<String> roles = session.getFactory().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() ] );
}
private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) {
if ( log.isTraceEnabled() ) {
log.debug( "ending loading collection [" + lce + "]" );
}
final SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
final EntityMode em = session.getEntityMode();
boolean hasNoQueuedAdds = lce.getCollection().endRead(); // warning: can cause a recursive calls! (proxy initialization)
if ( persister.getCollectionType().hasHolder( em ) ) {
getLoadContext().getPersistenceContext().addCollectionHolder( lce.getCollection() );
}
CollectionEntry ce = getLoadContext().getPersistenceContext().getCollectionEntry( lce.getCollection() );
if ( ce == null ) {
ce = getLoadContext().getPersistenceContext().addInitializedCollection( persister, lce.getCollection(), lce.getKey() );
}
else {
ce.postInitialize( lce.getCollection() );
}
boolean addToCache = hasNoQueuedAdds && // there were no queued additions
persister.hasCache() && // and the role has a cache
session.getCacheMode().isPutEnabled() &&
!ce.isDoremove(); // and this is not a forced initialization during flush
if ( addToCache ) {
addCollectionToCache( lce, persister );
}
if ( log.isDebugEnabled() ) {
log.debug( "collection fully initialized: " + MessageHelper.collectionInfoString(persister, lce.getKey(), session.getFactory() ) );
}
if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
session.getFactory().getStatisticsImplementor().loadCollection( persister.getRole() );
}
}
public void evictCollection(String roleName, Serializable id) throws HibernateException {
CollectionPersister p = getCollectionPersister(roleName);
if ( p.hasCache() ) {
if ( log.isDebugEnabled() ) {
log.debug( "evicting second-level cache: " + MessageHelper.collectionInfoString(p, id, this) );
}
CacheKey cacheKey = new CacheKey( id, p.getKeyType(), p.getRole(), EntityMode.POJO, this );
p.getCache().remove( cacheKey );
}
}
public void evictCollection(String roleName) throws HibernateException {
CollectionPersister p = getCollectionPersister(roleName);
if ( p.hasCache() ) {
if ( log.isDebugEnabled() ) {
log.debug( "evicting second-level cache: " + p.getRole() );
}
p.getCache().clear();
}
}
/**
* Try to initialize a collection from the cache
*
* @param id The id of the collection to initialize
* @param persister The collection persister
* @param collection The collection to initialize
* @param source The originating session
*
* @return true if we were able to initialize the collection from the cache;
* false otherwise.
*/
private boolean initializeCollectionFromCache(
Serializable id,
CollectionPersister persister,
PersistentCollection collection,
SessionImplementor source) {
if ( source.getLoadQueryInfluencers().hasEnabledFilters() && persister.isAffectedByEnabledFilters( source ) ) {
LOG.trace( "Disregarding cached version (if any) of collection due to enabled filters" );
return false;
}
final boolean useCache = persister.hasCache() && source.getCacheMode().isGetEnabled();
if ( !useCache ) {
return false;
}
final SessionFactoryImplementor factory = source.getFactory();
final CollectionDataAccess cacheAccessStrategy = persister.getCacheAccessStrategy();
final Object ck = cacheAccessStrategy.generateCacheKey( id, persister, factory, source.getTenantIdentifier() );
final Object ce = CacheHelper.fromSharedCache( source, ck, cacheAccessStrategy );
final StatisticsImplementor statistics = factory.getStatistics();
if ( statistics.isStatisticsEnabled() ) {
if ( ce == null ) {
statistics.collectionCacheMiss( persister.getNavigableRole(), cacheAccessStrategy.getRegion().getName() );
}
else {
statistics.collectionCacheHit( persister.getNavigableRole(), cacheAccessStrategy.getRegion().getName() );
}
}
if ( ce == null ) {
return false;
}
CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure().destructure( ce, factory );
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
cacheEntry.assemble( collection, persister, persistenceContext.getCollectionOwner( id, persister ) );
persistenceContext.getCollectionEntry( collection ).postInitialize( collection );
return true;
}
private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) {
LOG.tracev( "Ending loading collection [{0}]", lce );
final SharedSessionContractImplementor session = getLoadContext().getPersistenceContext().getSession();
// warning: can cause a recursive calls! (proxy initialization)
final boolean hasNoQueuedAdds = lce.getCollection().endRead();
if ( persister.getCollectionType().hasHolder() ) {
getLoadContext().getPersistenceContext().addCollectionHolder( lce.getCollection() );
}
CollectionEntry ce = getLoadContext().getPersistenceContext().getCollectionEntry( lce.getCollection() );
if ( ce == null ) {
ce = getLoadContext().getPersistenceContext().addInitializedCollection( persister, lce.getCollection(), lce.getKey() );
}
else {
ce.postInitialize( lce.getCollection() );
// if (ce.getLoadedPersister().getBatchSize() > 1) { // not the best place for doing this, moved into ce.postInitialize
// getLoadContext().getPersistenceContext().getBatchFetchQueue().removeBatchLoadableCollection(ce);
// }
}
// The collection has been completely initialized and added to the PersistenceContext.
if ( lce.getCollection().getOwner() != null ) {
// If the owner is bytecode-enhanced and the owner's collection value is uninitialized,
// then go ahead and set it to the newly initialized collection.
final BytecodeEnhancementMetadata bytecodeEnhancementMetadata =
persister.getOwnerEntityPersister().getInstrumentationMetadata();
if ( bytecodeEnhancementMetadata.isEnhancedForLazyLoading() ) {
// Lazy properties in embeddables/composites are not currently supported for embeddables (HHH-10480),
// so check to make sure the collection is not in an embeddable before checking to see if
// the collection is lazy.
// TODO: More will probably need to be done here when HHH-10480 is fixed..
if ( StringHelper.qualifier( persister.getRole() ).length() ==
persister.getOwnerEntityPersister().getEntityName().length() ) {
// Assume the collection is not in an embeddable.
// Strip off <entityName><dot> to get the collection property name.
final String propertyName = persister.getRole().substring(
persister.getOwnerEntityPersister().getEntityName().length() + 1
);
if ( !bytecodeEnhancementMetadata.isAttributeLoaded( lce.getCollection().getOwner(), propertyName ) ) {
int propertyIndex = persister.getOwnerEntityPersister().getEntityMetamodel().getPropertyIndex(
propertyName
);
persister.getOwnerEntityPersister().setPropertyValue(
lce.getCollection().getOwner(),
propertyIndex,
lce.getCollection()
);
}
}
}
}
// add to cache if:
boolean addToCache =
// there were no queued additions
hasNoQueuedAdds
// and the role has a cache
&& persister.hasCache()
// and this is not a forced initialization during flush
&& session.getCacheMode().isPutEnabled() && !ce.isDoremove();
if ( addToCache ) {
addCollectionToCache( lce, persister );
}
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Collection fully initialized: %s",
MessageHelper.collectionInfoString( persister, lce.getCollection(), lce.getKey(), session )
);
}
if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
session.getFactory().getStatistics().loadCollection( persister.getRole() );
}
}
private void evictCache(Object entity, EntityPersister persister, EventSource session, Object[] oldState) {
try {
SessionFactoryImplementor factory = persister.getFactory();
Set<String> collectionRoles = factory.getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() );
if ( collectionRoles == null || collectionRoles.isEmpty() ) {
return;
}
for ( String role : collectionRoles ) {
final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role );
if ( !collectionPersister.hasCache() ) {
// ignore collection if no caching is used
continue;
}
// this is the property this OneToMany relation is mapped by
String mappedBy = collectionPersister.getMappedByProperty();
if ( !collectionPersister.isManyToMany() &&
mappedBy != null && !mappedBy.isEmpty() ) {
int i = persister.getEntityMetamodel().getPropertyIndex( mappedBy );
Serializable oldId = null;
if ( oldState != null ) {
// in case of updating an entity we perhaps have to decache 2 entity collections, this is the
// old one
oldId = getIdentifier( session, oldState[i] );
}
Object ref = persister.getPropertyValue( entity, i );
Serializable id = getIdentifier( session, ref );
// only evict if the related entity has changed
if ( ( id != null && !id.equals( oldId ) ) || ( oldId != null && !oldId.equals( id ) ) ) {
if ( id != null ) {
evict( id, collectionPersister, session );
}
if ( oldId != null ) {
evict( oldId, collectionPersister, session );
}
}
}
else {
LOG.debug( "Evict CollectionRegion " + role );
final SoftLock softLock = collectionPersister.getCacheAccessStrategy().lockRegion();
session.getActionQueue().registerProcess( (success, session1) -> {
collectionPersister.getCacheAccessStrategy().unlockRegion( softLock );
} );
}
}
}
catch ( Exception e ) {
if ( PROPAGATE_EXCEPTION ) {
throw new IllegalStateException( e );
}
// don't let decaching influence other logic
LOG.error( "", e );
}
}
/**
* Try to initialize a collection from the cache
*
* @param id The id of the collection of initialize
* @param persister The collection persister
* @param collection The collection to initialize
* @param source The originating session
*
* @return true if we were able to initialize the collection from the cache;
* false otherwise.
*/
private boolean initializeCollectionFromCache(
Serializable id,
CollectionPersister persister,
PersistentCollection collection,
SessionImplementor source) {
if ( !source.getLoadQueryInfluencers().getEnabledFilters().isEmpty()
&& persister.isAffectedByEnabledFilters( source ) ) {
LOG.trace( "Disregarding cached version (if any) of collection due to enabled filters" );
return false;
}
final boolean useCache = persister.hasCache() && source.getCacheMode().isGetEnabled();
if ( !useCache ) {
return false;
}
final SessionFactoryImplementor factory = source.getFactory();
final CollectionDataAccess cacheAccessStrategy = persister.getCacheAccessStrategy();
final Object ck = cacheAccessStrategy.generateCacheKey( id, persister, factory, source.getTenantIdentifier() );
final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if ( ce == null ) {
factory.getStatistics().collectionCacheMiss(
persister.getNavigableRole(),
cacheAccessStrategy.getRegion().getName()
);
}
else {
factory.getStatistics().collectionCacheHit(
persister.getNavigableRole(),
cacheAccessStrategy.getRegion().getName()
);
}
}
if ( ce == null ) {
return false;
}
CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure().destructure(
ce,
factory
);
final PersistenceContext persistenceContext = source.getPersistenceContext();
cacheEntry.assemble( collection, persister, persistenceContext.getCollectionOwner( id, persister ) );
persistenceContext.getCollectionEntry( collection ).postInitialize( collection );
// addInitializedCollection(collection, persister, id);
return true;
}
/**
* Try to initialize a collection from the cache
*/
private boolean initializeCollectionFromCache(
Serializable id,
CollectionPersister persister,
PersistentCollection collection,
SessionImplementor source)
throws HibernateException {
if ( !source.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( source ) ) {
log.trace( "disregarding cached version (if any) of collection due to enabled filters ");
return false;
}
final boolean useCache = persister.hasCache() &&
source.getCacheMode().isGetEnabled();
if ( !useCache ) {
return false;
}
else {
final SessionFactoryImplementor factory = source.getFactory();
final CacheKey ck = new CacheKey(
id,
persister.getKeyType(),
persister.getRole(),
source.getEntityMode(),
source.getFactory()
);
Object ce = persister.getCache().get( ck, source.getTimestamp() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if (ce==null) {
factory.getStatisticsImplementor().secondLevelCacheMiss(
persister.getCache().getRegionName()
);
}
else {
factory.getStatisticsImplementor().secondLevelCacheHit(
persister.getCache().getRegionName()
);
}
}
if (ce==null) {
return false;
}
else {
CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure()
.destructure(ce, factory);
final PersistenceContext persistenceContext = source.getPersistenceContext();
cacheEntry.assemble(
collection,
persister,
persistenceContext.getCollectionOwner(id, persister)
);
persistenceContext.getCollectionEntry(collection).postInitialize(collection);
//addInitializedCollection(collection, persister, id);
return true;
}
}
}