下面列出了怎么用org.hibernate.cache.spi.entry.CacheEntry的API类实例代码及写法,或者点击链接到github查看源代码。
private Class<?> getSubclassName(Object cacheEntry, boolean useStructuredCache) {
String subclassName = null;
if (useStructuredCache) {
@SuppressWarnings("unchecked")
Map structuredCacheEntry = (Map) cacheEntry;
subclassName = (String) structuredCacheEntry.get(STRUCTURED_CACHE_ENTRY_SUBCLASS_KEY);
} else {
subclassName = ((CacheEntry) cacheEntry).getSubclass();
}
Class<?> clazz;
try {
clazz = Class.forName(subclassName);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(subclassName + " class is not found.", e);
}
return clazz;
}
@Test
public void put_classVersionApplicable_true() throws Exception {
givenRegionWithDefaultProperties();
String key = "greeting";
CacheEntry cacheEntry = mock(CacheEntry.class);
when(cacheEntry.getSubclass()).thenReturn(String.class.getName());
ArgumentCaptor<CacheItem> cacheItemArgumentCaptor = ArgumentCaptor.forClass(CacheItem.class);
generalDataMemcachedRegion.put(key, cacheEntry);
verify(memcachedAdapter).set(eq(cacheNamespace), eq(refineKey(key)), cacheItemArgumentCaptor.capture(),
eq(generalDataMemcachedRegion.getExpiryInSeconds()));
CacheItem cacheItem = cacheItemArgumentCaptor.getValue();
assertThat(cacheItem.getCacheEntry()).isEqualTo(cacheEntry);
assertThat(cacheItem.getTargetClassName()).isEqualTo(String.class.getName());
}
private Object initializeLazyPropertiesFromCache(
final String fieldName,
final Object entity,
final SharedSessionContractImplementor session,
final EntityEntry entry,
final CacheEntry cacheEntry) {
LOG.trace( "Initializing lazy properties from second-level cache" );
Object result = null;
Serializable[] disassembledValues = cacheEntry.getDisassembledState();
final Object[] snapshot = entry.getLoadedState();
for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
final Serializable cachedValue = disassembledValues[lazyPropertyNumbers[j]];
final Type lazyPropertyType = lazyPropertyTypes[j];
final String propertyName = lazyPropertyNames[j];
if (cachedValue == LazyPropertyInitializer.UNFETCHED_PROPERTY) {
if (fieldName.equals(propertyName)) {
result = LazyPropertyInitializer.UNFETCHED_PROPERTY;
}
// don't try to initialize the unfetched property
}
else {
final Object propValue = lazyPropertyType.assemble(
cachedValue,
session,
entity
);
if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
result = propValue;
}
}
}
LOG.trace( "Done initializing lazy properties" );
return result;
}
@Override
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
return new StandardCacheEntryImpl(
state,
persister,
version,
session,
entity
);
}
@Override
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
return new StandardCacheEntryImpl(
state,
persister,
version,
session,
entity
);
}
private Object processCachedEntry(
final LoadEvent event,
final EntityPersister persister,
final Object ce,
final SessionImplementor source,
final EntityKey entityKey) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, source.getFactory() );
if(entry.isReferenceEntry()) {
if( event.getInstanceToLoad() != null ) {
throw new HibernateException(
"Attempt to load entity [%s] from cache using provided object instance, but cache " +
"is storing references: "+ event.getEntityId());
}
else {
return convertCacheReferenceEntryToEntity( (ReferenceCacheEntryImpl) entry,
event.getSession(), entityKey);
}
}
else {
Object entity = convertCacheEntryToEntity( entry, event.getEntityId(), persister, event, entityKey );
if ( !persister.isInstance( entity ) ) {
throw new WrongClassException(
"loaded object was of wrong class " + entity.getClass(),
event.getEntityId(),
persister.getEntityName()
);
}
return entity;
}
}
/**
* Check if class version comparable.
*/
public static boolean checkIfClassVersionApplicable(Object cacheEntry, boolean useStructuredCache) {
if (!useStructuredCache && cacheEntry instanceof CacheEntry) {
return true;
}
if (useStructuredCache && cacheEntry instanceof Map) {
return true;
}
return false;
}
@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;
} );
} );
}
/**
* The entity instance is not in the session cache
*/
private Object instanceNotYetLoaded(
final ResultSet rs,
final int i,
final Loadable persister,
final String rowIdAlias,
final EntityKey key,
final LockMode lockMode,
final EntityKey optionalObjectKey,
final Object optionalObject,
final List hydratedObjects,
final SharedSessionContractImplementor session)
throws HibernateException, SQLException {
final String instanceClass = getInstanceClass(
rs,
i,
persister,
key.getIdentifier(),
session
);
// see if the entity defines reference caching, and if so use the cached reference (if one).
if ( session.getCacheMode().isGetEnabled() && persister.canUseReferenceCacheEntries() ) {
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(
key.getIdentifier(),
persister,
session.getFactory(),
session.getTenantIdentifier()
);
final Object cachedEntry = CacheHelper.fromSharedCache( session, ck, cache );
if ( cachedEntry != null ) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory );
return ( (ReferenceCacheEntryImpl) entry ).getReference();
}
}
final Object object;
if ( optionalObjectKey != null && key.equals( optionalObjectKey ) ) {
//its the given optional object
object = optionalObject;
}
else {
// instantiate a new instance
object = session.instantiate( instanceClass, key.getIdentifier() );
}
//need to hydrate it.
// grab its state from the ResultSet and keep it in the Session
// (but don't yet initialize the object itself)
// note that we acquire LockMode.READ even if it was not requested
LockMode acquiredLockMode = lockMode == LockMode.NONE ? LockMode.READ : lockMode;
loadFromResultSet(
rs,
i,
object,
instanceClass,
key,
rowIdAlias,
acquiredLockMode,
persister,
session
);
//materialize associations (and initialize the object) later
hydratedObjects.add( object );
return object;
}
@Override
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
return cacheEntryHelper.buildCacheEntry( entity, state, version, session );
}
@Override
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
return new ReferenceCacheEntryImpl( entity, persister );
}
@Override
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
throw new HibernateException( "Illegal attempt to build cache entry for non-cached entity" );
}
private Object convertCacheEntryToEntity(
CacheEntry entry,
Serializable entityId,
EntityPersister persister,
LoadEvent event,
EntityKey entityKey) {
final EventSource session = event.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final EntityPersister subclassPersister;
if ( traceEnabled ) {
LOG.tracef(
"Converting second-level cache entry [%s] into entity : %s",
entry,
MessageHelper.infoString( persister, entityId, factory )
);
}
final Object entity;
subclassPersister = factory.getEntityPersister( entry.getSubclass() );
final Object optionalObject = event.getInstanceToLoad();
entity = optionalObject == null
? session.instantiate( subclassPersister, entityId )
: optionalObject;
// make it circular-reference safe
TwoPhaseLoad.addUninitializedCachedEntity(
entityKey,
entity,
subclassPersister,
LockMode.NONE,
entry.getVersion(),
session
);
final PersistenceContext persistenceContext = session.getPersistenceContext();
final Object[] values;
final Object version;
final boolean isReadOnly;
final Type[] types = subclassPersister.getPropertyTypes();
// initializes the entity by (desired) side-effect
values = ( (StandardCacheEntryImpl) entry ).assemble(
entity, entityId, subclassPersister, session.getInterceptor(), session
);
if ( ( (StandardCacheEntryImpl) entry ).isDeepCopyNeeded() ) {
TypeHelper.deepCopy(
values,
types,
subclassPersister.getPropertyUpdateability(),
values,
session
);
}
version = Versioning.getVersion( values, subclassPersister );
LOG.tracef( "Cached Version : %s", version );
final Object proxy = persistenceContext.getProxy( entityKey );
if ( proxy != null ) {
// there is already a proxy for this impl
// only set the status to read-only if the proxy is read-only
isReadOnly = ( (HibernateProxy) proxy ).getHibernateLazyInitializer().isReadOnly();
}
else {
isReadOnly = session.isDefaultReadOnly();
}
persistenceContext.addEntry(
entity,
( isReadOnly ? Status.READ_ONLY : Status.MANAGED ),
values,
null,
entityId,
version,
LockMode.NONE,
true,
subclassPersister,
false
);
subclassPersister.afterInitialize( entity, session );
persistenceContext.initializeNonLazyCollections();
//PostLoad is needed for EJB3
PostLoadEvent postLoadEvent = event.getPostLoadEvent()
.setEntity( entity )
.setId( entityId )
.setPersister( persister );
for ( PostLoadEventListener listener : postLoadEventListeners( session ) ) {
listener.onPostLoad( postLoadEvent );
}
return entity;
}
@Override
public void execute() throws HibernateException {
nullifyTransientReferencesIfNotAlready();
final EntityPersister persister = getPersister();
final SharedSessionContractImplementor session = getSession();
final Object instance = getInstance();
final Serializable id = getId();
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
if ( !veto ) {
persister.insert( id, getState(), instance, session );
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() ) {
version = Versioning.getVersion( getState(), persister );
}
entry.postUpdate( instance, getState(), version );
}
persistenceContext.registerInsertedKey( persister, getId() );
}
final SessionFactoryImplementor factory = session.getFactory();
if ( isCachePutEnabled( persister, session ) ) {
final CacheEntry ce = persister.buildCacheEntry(
instance,
getState(),
version,
session
);
cacheEntry = 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(
StatsHelper.INSTANCE.getRootEntityRole( persister ),
cache.getRegion().getName()
);
}
}
handleNaturalIdPostSaveNotifications( id );
postInsert();
if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
factory.getStatistics().insertEntity( getPersister().getEntityName() );
}
markExecuted();
}
CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session);
CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session);