HHH-8654 - Ability to get notified of interesting Session events

(cherry picked from commit 449c558365)

Conflicts:

	hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java
This commit is contained in:
Steve Ebersole 2013-11-15 13:04:18 -06:00
parent 50870c742f
commit 4605941df1
10 changed files with 154 additions and 79 deletions

View File

@ -198,22 +198,26 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
EntityPersister persister = getPersister();
if ( success && isCachePutEnabled( persister, getSession() ) ) {
final CacheKey ck = getSession().generateCacheKey( getId(), persister.getIdentifierType(), persister.getRootEntityName() );
try {
getSession().getEventListenerManager().cachePutStart();
final boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
final boolean put = cacheAfterInsert( persister, ck );
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
getSession().getFactory().getStatisticsImplementor()
.secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
}
}
finally {
getSession().getEventListenerManager().cachePutEnd();
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
getSession().getFactory().getStatisticsImplementor()
.secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
}
}
postCommitInsert();
}
private boolean cacheAfterInsert(EntityPersister persister, CacheKey ck) {
try {
getSession().getEventListenerManager().cachePutStart();
return persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
}
finally {
getSession().getEventListenerManager().cachePutEnd();
}
}
@Override
protected boolean hasPostCommitEventListeners() {
return ! listenerGroup( EventType.POST_COMMIT_INSERT ).isEmpty();

View File

@ -188,14 +188,9 @@ public final class EntityUpdateAction extends EntityAction {
CacheEntry ce = persister.buildCacheEntry( instance,state, nextVersion, getSession() );
cacheEntry = persister.getCacheEntryStructure().structure( ce );
try {
final boolean put = persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion );
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
}
}
finally {
final boolean put = cacheUpdate( persister, previousVersion, ck );
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
}
}
}
@ -216,6 +211,16 @@ public final class EntityUpdateAction extends EntityAction {
}
}
private boolean cacheUpdate(EntityPersister persister, Object previousVersion, CacheKey ck) {
try {
getSession().getEventListenerManager().cachePutStart();
return persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion );
}
finally {
getSession().getEventListenerManager().cachePutEnd();
}
}
private boolean preUpdate() {
boolean veto = false;
EventListenerGroup<PreUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_UPDATE );
@ -291,16 +296,10 @@ public final class EntityUpdateAction extends EntityAction {
);
if ( success && cacheEntry!=null /*!persister.isCacheInvalidationRequired()*/ ) {
try {
session.getEventListenerManager().cachePutStart();
final boolean put = persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock );
final boolean put = cacheAfterUpdate( persister, ck );
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
}
}
finally {
session.getEventListenerManager().cachePutEnd();
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
}
}
else {
@ -310,5 +309,15 @@ public final class EntityUpdateAction extends EntityAction {
postCommitUpdate();
}
private boolean cacheAfterUpdate(EntityPersister persister, CacheKey ck) {
try {
getSession().getEventListenerManager().cachePutStart();
return persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock );
}
finally {
getSession().getEventListenerManager().cachePutEnd();
}
}
}

View File

@ -0,0 +1,67 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.internal;
import java.io.Serializable;
import org.hibernate.cache.spi.CacheKey;
import org.hibernate.cache.spi.NaturalIdCacheKey;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.RegionAccessStrategy;
import org.hibernate.engine.spi.SessionImplementor;
/**
* @author Steve Ebersole
*/
public class CacheHelper {
public static Serializable fromSharedCache(
SessionImplementor session,
NaturalIdCacheKey cacheKey,
NaturalIdRegionAccessStrategy cacheAccessStrategy) {
return fromSharedCache( session, (Object) cacheKey, cacheAccessStrategy );
}
private static Serializable fromSharedCache(
SessionImplementor session,
Object cacheKey,
RegionAccessStrategy cacheAccessStrategy) {
Serializable cachedValue = null;
try {
session.getEventListenerManager().cacheGetStart();
cachedValue = (Serializable) cacheAccessStrategy.get( cacheKey, session.getTimestamp() );
}
finally {
session.getEventListenerManager().cacheGetEnd( cachedValue != null );
}
return cachedValue;
}
public static Serializable fromSharedCache(
SessionImplementor session,
CacheKey cacheKey,
RegionAccessStrategy cacheAccessStrategy) {
return fromSharedCache( session, (Object) cacheKey, cacheAccessStrategy );
}
}

View File

@ -251,7 +251,7 @@ public class NaturalIdXrefDelegate {
final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session() );
final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy();
pk = (Serializable) naturalIdCacheAccessStrategy.get( naturalIdCacheKey, session().getTimestamp() );
pk = CacheHelper.fromSharedCache( session(), naturalIdCacheKey, naturalIdCacheAccessStrategy );
// Found in second-level cache, store in session cache
final SessionFactoryImplementor factory = session().getFactory();

View File

@ -1898,8 +1898,9 @@ public class StatefulPersistenceContext implements PersistenceContext {
switch ( source ) {
case LOAD: {
if (naturalIdCacheAccessStrategy.get(naturalIdCacheKey, session.getTimestamp()) != null) {
return; // prevent identical re-cachings
if ( CacheHelper.fromSharedCache( session, naturalIdCacheKey, naturalIdCacheAccessStrategy ) != null ) {
// prevent identical re-cachings
return;
}
final boolean put = naturalIdCacheAccessStrategy.putFromLoad(
naturalIdCacheKey,
@ -1966,7 +1967,11 @@ public class StatefulPersistenceContext implements PersistenceContext {
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
naturalIdCacheAccessStrategy.unlockItem( previousCacheKey, removalLock );
if (success) {
final boolean put = naturalIdCacheAccessStrategy.afterUpdate( naturalIdCacheKey, id, lock );
final boolean put = naturalIdCacheAccessStrategy.afterUpdate(
naturalIdCacheKey,
id,
lock
);
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor()

View File

@ -34,6 +34,7 @@ import org.jboss.logging.Logger;
import org.hibernate.EntityMode;
import org.hibernate.cache.spi.CacheKey;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -216,12 +217,12 @@ public class BatchFetchQueue {
private boolean isCached(EntityKey entityKey, EntityPersister persister) {
if ( persister.hasCache() ) {
CacheKey key = context.getSession().generateCacheKey(
final CacheKey key = context.getSession().generateCacheKey(
entityKey.getIdentifier(),
persister.getIdentifierType(),
entityKey.getEntityName()
);
return persister.getCacheAccessStrategy().get( key, context.getSession().getTimestamp() ) != null;
return CacheHelper.fromSharedCache( context.getSession(), key, persister.getCacheAccessStrategy() ) != null;
}
return false;
}
@ -334,7 +335,7 @@ public class BatchFetchQueue {
persister.getKeyType(),
persister.getRole()
);
return persister.getCacheAccessStrategy().get( cacheKey, context.getSession().getTimestamp() ) != null;
return CacheHelper.fromSharedCache( context.getSession(), cacheKey, persister.getCacheAccessStrategy() ) != null;
}
return false;
}

View File

@ -29,6 +29,7 @@ import org.hibernate.HibernateException;
import org.hibernate.cache.spi.CacheKey;
import org.hibernate.cache.spi.entry.CollectionCacheEntry;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -123,27 +124,18 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
if (!useCache) return false;
final SessionFactoryImplementor factory = source.getFactory();
final CacheKey ck = source.generateCacheKey( id, persister.getKeyType(), persister.getRole() );
final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() );
Object ce = null;
try {
source.getEventListenerManager().cacheGetStart();
ce = persister.getCacheAccessStrategy().get(ck, source.getTimestamp());
if ( factory.getStatistics().isStatisticsEnabled() ) {
if (ce == null) {
factory.getStatisticsImplementor()
.secondLevelCacheMiss( persister.getCacheAccessStrategy().getRegion().getName() );
}
else {
factory.getStatisticsImplementor()
.secondLevelCacheHit( persister.getCacheAccessStrategy().getRegion().getName() );
}
if ( factory.getStatistics().isStatisticsEnabled() ) {
if (ce == null) {
factory.getStatisticsImplementor()
.secondLevelCacheMiss( persister.getCacheAccessStrategy().getRegion().getName() );
}
else {
factory.getStatisticsImplementor()
.secondLevelCacheHit( persister.getCacheAccessStrategy().getRegion().getName() );
}
}
finally {
source.getEventListenerManager().cacheGetEnd( ce == null );
}
if ( ce == null ) {

View File

@ -37,6 +37,7 @@ import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.internal.TwoPhaseLoad;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.EntityEntry;
@ -547,26 +548,18 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
persister.getRootEntityName()
);
Object ce = null;
try {
source.getEventListenerManager().cacheGetStart();
ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if ( ce == null ) {
factory.getStatisticsImplementor().secondLevelCacheMiss(
persister.getCacheAccessStrategy().getRegion().getName()
);
}
else {
factory.getStatisticsImplementor().secondLevelCacheHit(
persister.getCacheAccessStrategy().getRegion().getName()
);
}
final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if ( ce == null ) {
factory.getStatisticsImplementor().secondLevelCacheMiss(
persister.getCacheAccessStrategy().getRegion().getName()
);
}
else {
factory.getStatisticsImplementor().secondLevelCacheHit(
persister.getCacheAccessStrategy().getRegion().getName()
);
}
}
finally {
source.getEventListenerManager().cacheGetEnd( ce == null );
}
if ( ce == null ) {

View File

@ -61,6 +61,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.dialect.pagination.NoopLimitHandler;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.internal.TwoPhaseLoad;
import org.hibernate.engine.jdbc.ColumnNameCache;
import org.hibernate.engine.spi.EntityEntry;
@ -1594,13 +1595,14 @@ public abstract class Loader {
// see if the entity defines reference caching, and if so use the cached reference (if one).
if ( persister.canUseReferenceCacheEntries() ) {
final Object cachedEntry = persister.getCacheAccessStrategy().get(
final Object cachedEntry = CacheHelper.fromSharedCache(
session,
session.generateCacheKey(
key.getIdentifier(),
persister.getEntityMetamodel().getEntityType(),
key.getEntityName()
),
session.getTimestamp()
persister.getCacheAccessStrategy()
);
if ( cachedEntry != null ) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory );

View File

@ -62,6 +62,7 @@ import org.hibernate.cache.spi.entry.StructuredCacheEntry;
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
@ -1222,10 +1223,10 @@ public abstract class AbstractEntityPersister
}
if ( hasCache() ) {
CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() );
Object ce = getCacheAccessStrategy().get( cacheKey, session.getTimestamp() );
if (ce!=null) {
CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
final CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() );
final Object ce = CacheHelper.fromSharedCache( session, cacheKey, getCacheAccessStrategy() );
if ( ce != null ) {
final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
if ( !cacheEntry.areLazyPropertiesUnfetched() ) {
//note early exit here:
return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
@ -4302,8 +4303,9 @@ public abstract class AbstractEntityPersister
// check to see if it is in the second-level cache
if ( hasCache() ) {
CacheKey ck = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() );
if ( getCacheAccessStrategy().get( ck, session.getTimestamp() ) != null ) {
final CacheKey ck = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() );
final Object ce = CacheHelper.fromSharedCache( session, ck, getCacheAccessStrategy() );
if ( ce != null ) {
return Boolean.FALSE;
}
}