Skip to content

Commit

Permalink
HHH-11356 - Adjust the 2nd-Cache SPIs to better reflect supported uses
Browse files Browse the repository at this point in the history
HHH-12323 - Update Statistics API and SPI based on changes to 2nd level caching changes

- initial work on migrating hibernate-jcache to new SPIs including a more template-style approach to writing a RegionFactory (o.h.cache.spi.support)
  • Loading branch information
sebersole committed Mar 22, 2018
1 parent f432ece commit 638ebf0
Show file tree
Hide file tree
Showing 83 changed files with 1,335 additions and 1,993 deletions.
Expand Up @@ -525,7 +525,7 @@ To use the `JCacheRegionFactory`, you need to specify the following configuratio
----
<property
name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.jcache.JCacheRegionFactory"/>
value="jcache"/>
----
====

Expand Down
Expand Up @@ -74,6 +74,7 @@ public EnabledCaching(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;

this.regionFactory = getSessionFactory().getSessionFactoryOptions().getServiceRegistry().getService( RegionFactory.class );
this.regionFactory.start( sessionFactory.getSessionFactoryOptions(), sessionFactory.getProperties() );

if ( getSessionFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
final TimestampsRegion timestampsRegion = regionFactory.buildTimestampsRegion(
Expand Down
Expand Up @@ -47,6 +47,11 @@ public void start(SessionFactoryOptions settings, Map configValues) throws Cache
public void stop() {
}

@Override
public String qualify(String regionName) {
return regionName;
}

@Override
public boolean isMinimalPutsEnabledByDefault() {
return false;
Expand All @@ -59,7 +64,7 @@ public AccessType getDefaultAccessType() {

@Override
public long nextTimestamp() {
return System.currentTimeMillis() / 100;
return System.currentTimeMillis();
}

@Override
Expand Down
Expand Up @@ -93,7 +93,7 @@ public boolean put(

try {
session.getEventListenerManager().cachePutStart();
cacheRegion.getAccess().addToCache( key, cacheItem );
cacheRegion.getStorageAccess().putIntoCache( key, cacheItem );
}
finally {
session.getEventListenerManager().cachePutEnd();
Expand Down Expand Up @@ -189,7 +189,7 @@ private CacheItem getCachedData(QueryKey key, SharedSessionContractImplementor s
CacheItem cachedItem = null;
try {
session.getEventListenerManager().cacheGetStart();
cachedItem = (CacheItem) cacheRegion.getAccess().getFromCache( key );
cachedItem = (CacheItem) cacheRegion.getStorageAccess().getFromCache( key );
}
finally {
session.getEventListenerManager().cacheGetEnd( cachedItem != null );
Expand Down Expand Up @@ -288,7 +288,7 @@ public String toString() {

@Override
public void clear() throws CacheException {
cacheRegion.getAccess().clearCache();
cacheRegion.getStorageAccess().clearCache();
}

public static class CacheItem implements Serializable {
Expand Down
Expand Up @@ -57,7 +57,7 @@ public void preInvalidate(

//put() has nowait semantics, is this really appropriate?
//note that it needs to be async replication, never local or sync
timestampsRegion.getAccess().addToCache( space, ts );
timestampsRegion.getStorageAccess().putIntoCache( space, ts );
}
finally {
session.getEventListenerManager().cachePutEnd();
Expand All @@ -84,7 +84,7 @@ public void invalidate(

try {
session.getEventListenerManager().cachePutStart();
timestampsRegion.getAccess().addToCache( space, ts );
timestampsRegion.getStorageAccess().putIntoCache( space, ts );
}
finally {
session.getEventListenerManager().cachePutEnd();
Expand Down Expand Up @@ -135,7 +135,7 @@ private Long getLastUpdateTimestampForSpace(Serializable space, SharedSessionCon
Long ts = null;
try {
session.getEventListenerManager().cacheGetStart();
ts = (Long) timestampsRegion.getAccess().getFromCache( space );
ts = (Long) timestampsRegion.getStorageAccess().getFromCache( space );
}
finally {
session.getEventListenerManager().cacheGetEnd( ts != null );
Expand Down
Expand Up @@ -6,37 +6,14 @@
*/
package org.hibernate.cache.spi;

import org.hibernate.cache.spi.support.StorageAccess;

/**
* Specialized Region whose data is accessed directly - not requiring
* key wrapping, e.g.
*
* @author Steve Ebersole
*/
public interface DirectAccessRegion extends Region {
interface DataAccess {
Object getFromCache(Object key);
void addToCache(Object key, Object value);
void removeFromCache(Object key);
void clearCache();
}

DataAccess getAccess();
// Object get(Object key, SharedSessionContractImplementor session);
// void put(Object key, Object value, SharedSessionContractImplementor session);
//
// /**
// * Forcibly evict an item from the cache immediately without regard for transaction
// * isolation. This behavior is exactly Hibernate legacy behavior, but it is also required
// * by JPA - so we cannot remove it.
// *
// * @param key The key of the item to remove
// */
// void evict(Object key);
//
// /**
// * Forcibly evict all items from the cache immediately without regard for transaction
// * isolation. This behavior is exactly Hibernate legacy behavior, but it is also required
// * by JPA - so we cannot remove it.
// */
// void evictAll();
StorageAccess getStorageAccess();
}
Expand Up @@ -36,7 +36,7 @@ public interface QueryResultRegionAccess extends QueryCache {
*/
@Override
default void clear() throws CacheException {
getRegion().getAccess().clearCache();
getRegion().getStorageAccess().clearCache();
}

/**
Expand Down
Expand Up @@ -13,8 +13,4 @@
* @author Steve Ebersole
*/
public interface QueryResultsRegion extends DirectAccessRegion {
@Override
default void clear() {
getAccess().clearCache();
}
}
Expand Up @@ -59,7 +59,11 @@ public interface RegionFactory extends Service, Stoppable {
*/
AccessType getDefaultAccessType();

CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session);
String qualify(String regionName);

default CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session) {
return new StandardCacheTransactionSynchronization( this );
}

/**
* Generate a timestamp. This value is generally used for purpose of
Expand Down
Expand Up @@ -6,11 +6,17 @@
*/
package org.hibernate.cache.spi;

import org.hibernate.metamodel.model.domain.NavigableRole;

import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.logging.annotations.ValidIdRange;

import static org.jboss.logging.Logger.Level.WARN;

/**
* @author Steve Ebersole
*/
Expand All @@ -22,11 +28,18 @@ public interface SecondLevelCacheLogger extends BasicLogger {
"org.hibernate.orm.cache"
);

enum RegionAccessType {
ENTITY,
NATURAL_ID,
COLLECTION,
QUERY_RESULTS,
TIMESTAMPS
}
@LogMessage( level = WARN )
@Message(
value = "Read-only caching was requested for mutable entity [%s]",
id = 90001001
)
void readOnlyCachingMutableEntity(NavigableRole navigableRole);

@LogMessage( level = WARN )
@Message(
value = "Read-only caching was requested for mutable natural-id for entity [%s]",
id = 90001002
)
void readOnlyCachingMutableNaturalId(NavigableRole navigableRole);

}
@@ -0,0 +1,16 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.cache.spi;

/**
* @author Steve Ebersole
*/
public class StandardCacheTransactionSynchronization extends AbstractCacheTransactionSynchronization {
public StandardCacheTransactionSynchronization(RegionFactory regionFactory) {
super( regionFactory );
}
}
Expand Up @@ -12,6 +12,6 @@
public interface TimestampsRegion extends DirectAccessRegion {
@Override
default void clear() {
getAccess().clearCache();
getStorageAccess().clearCache();
}
}
Expand Up @@ -95,7 +95,7 @@ public void accept(Serializable serializable) {

@Override
default void clear() throws CacheException {
getRegion().getAccess().clearCache();
getRegion().getStorageAccess().clearCache();
}

@Override
Expand Down
Expand Up @@ -4,13 +4,9 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.testing.cache;
package org.hibernate.cache.spi.support;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.cache.spi.AbstractDomainDataRegion;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
Expand All @@ -23,63 +19,47 @@
public abstract class AbstractCachedDomainDataAccess implements CachedDomainDataAccess, AbstractDomainDataRegion.Destructible {
private static final Logger log = Logger.getLogger( AbstractCachedDomainDataAccess.class );

private final DomainDataRegionImpl region;

private Map data;
private final DomainDataRegion region;
private final DomainDataStorageAccess storageAccess;

protected AbstractCachedDomainDataAccess(DomainDataRegionImpl region) {
protected AbstractCachedDomainDataAccess(
DomainDataRegion region,
DomainDataStorageAccess storageAccess) {
this.region = region;
this.storageAccess = storageAccess;
}

@Override
public DomainDataRegionImpl getRegion() {
public DomainDataRegion getRegion() {
return region;
}

protected Object getFromCache(Object key) {
log.debugf( "Locating entry in cache data map [region=`%s`] : %s", key );
if ( data == null ) {
return null;
}
return data.get( key );
log.debugf( "Locating entry in cache storage [region=`%s`] : %s", key );
return storageAccess.getFromCache( key );
}

@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void addToCache(Object key, Object value) {
log.debugf( "Adding entry to cache data map [region=`%s`] : %s -> %s", getRegion().getName(), key, value );
getOrMakeData().put( key, value );
log.debugf( "Adding entry to cache storage [region=`%s`] : %s -> %s", getRegion().getName(), key, value );
storageAccess.putIntoCache( key, value );
}

@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void removeFromCache(Object key) {
log.debugf( "Removing entry from cache data map [region=`%s`] : %s", key );
if ( data != null ) {
data.remove( key );
}
log.debugf( "Removing entry from cache storage [region=`%s`] : %s", key );
storageAccess.removeFromCache( key );
}

@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void clearCache() {
log.debugf( "Clearing cache data map [region=`%s`]" );
if ( data != null ) {
data.clear();
}
}

public Map getData() {
return data == null ? Collections.emptyMap() : Collections.unmodifiableMap( data );
}

private Map getOrMakeData() {
if ( data == null ) {
data = new ConcurrentHashMap();
}
return data;
storageAccess.clearCache();
}

@Override
public boolean contains(Object key) {
return data != null && data.containsKey( key );
return storageAccess.contains( key );
}

@Override
Expand Down Expand Up @@ -142,8 +122,6 @@ public void evictAll() {

@Override
public void destroy() {
if ( data != null ) {
data.clear();
}
storageAccess.release();
}
}
Expand Up @@ -4,8 +4,11 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.testing.cache;
package org.hibernate.cache.spi.support;

import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SessionFactoryImplementor;
Expand All @@ -15,22 +18,29 @@
/**
* @author Steve Ebersole
*/
public abstract class BaseCollectionDataAccess
public abstract class AbstractCollectionDataAccess
extends AbstractCachedDomainDataAccess
implements CollectionDataAccess {

public BaseCollectionDataAccess(DomainDataRegionImpl region) {
super( region );
private final CacheKeysFactory keysFactory;

public AbstractCollectionDataAccess(
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
CollectionDataCachingConfig config) {
super( region, storageAccess );
this.keysFactory = keysFactory;
}

@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return getRegion().getEffectiveKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
return keysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
}

@Override
public Object getCacheKeyId(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getCollectionId( cacheKey );
return keysFactory.getCollectionId( cacheKey );
}

@Override
Expand Down

0 comments on commit 638ebf0

Please sign in to comment.