HHH-13586 : ClassCastException when using a single region name for both entity and query results
(cherry picked from commit 2076c68ddf
)
This commit is contained in:
parent
1f48df3ee5
commit
6c4643f265
|
@ -48,6 +48,7 @@ import org.hibernate.pretty.MessageHelper;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Strong Liu
|
* @author Strong Liu
|
||||||
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildingContext {
|
public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildingContext {
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EnabledCaching.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EnabledCaching.class );
|
||||||
|
@ -57,6 +58,10 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
|
||||||
|
|
||||||
private final Map<String,Region> regionsByName = new ConcurrentHashMap<>();
|
private final Map<String,Region> regionsByName = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// A map by name for QueryResultsRegion instances that have the same name as a Region
|
||||||
|
// in #regionsByName.
|
||||||
|
private final Map<String, QueryResultsRegion> queryResultsRegionsByDuplicateName = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final Map<NavigableRole,EntityDataAccess> entityAccessMap = new ConcurrentHashMap<>();
|
private final Map<NavigableRole,EntityDataAccess> entityAccessMap = new ConcurrentHashMap<>();
|
||||||
private final Map<NavigableRole,NaturalIdDataAccess> naturalIdAccessMap = new ConcurrentHashMap<>();
|
private final Map<NavigableRole,NaturalIdDataAccess> naturalIdAccessMap = new ConcurrentHashMap<>();
|
||||||
private final Map<NavigableRole,CollectionDataAccess> collectionAccessMap = new ConcurrentHashMap<>();
|
private final Map<NavigableRole,CollectionDataAccess> collectionAccessMap = new ConcurrentHashMap<>();
|
||||||
|
@ -204,6 +209,8 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Region getRegion(String regionName) {
|
public Region getRegion(String regionName) {
|
||||||
|
// The Region in regionsByName has precedence over the
|
||||||
|
// QueryResultsRegion in #queryResultsRegionsByDuplicateName
|
||||||
return regionsByName.get( regionName );
|
return regionsByName.get( regionName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,12 +495,23 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
|
||||||
}
|
}
|
||||||
|
|
||||||
protected QueryResultsCache makeQueryResultsRegionAccess(String regionName) {
|
protected QueryResultsCache makeQueryResultsRegionAccess(String regionName) {
|
||||||
final QueryResultsRegion region = (QueryResultsRegion) regionsByName.computeIfAbsent(
|
final Region region = regionsByName.computeIfAbsent(
|
||||||
regionName,
|
regionName,
|
||||||
this::makeQueryResultsRegion
|
this::makeQueryResultsRegion
|
||||||
);
|
);
|
||||||
|
final QueryResultsRegion queryResultsRegion;
|
||||||
|
if ( QueryResultsRegion.class.isInstance( region ) ) {
|
||||||
|
queryResultsRegion = (QueryResultsRegion) region;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// There was already a different type of Region with the same name.
|
||||||
|
queryResultsRegion = queryResultsRegionsByDuplicateName.computeIfAbsent(
|
||||||
|
regionName,
|
||||||
|
this::makeQueryResultsRegion
|
||||||
|
);
|
||||||
|
}
|
||||||
final QueryResultsCacheImpl regionAccess = new QueryResultsCacheImpl(
|
final QueryResultsCacheImpl regionAccess = new QueryResultsCacheImpl(
|
||||||
region,
|
queryResultsRegion,
|
||||||
timestampsCache
|
timestampsCache
|
||||||
);
|
);
|
||||||
namedQueryResultsCacheMap.put( regionName, regionAccess );
|
namedQueryResultsCacheMap.put( regionName, regionAccess );
|
||||||
|
@ -502,20 +520,9 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
|
||||||
}
|
}
|
||||||
|
|
||||||
protected QueryResultsRegion makeQueryResultsRegion(String regionName) {
|
protected QueryResultsRegion makeQueryResultsRegion(String regionName) {
|
||||||
// make sure there is not an existing domain-data region with that name..
|
|
||||||
final Region existing = regionsByName.get( regionName );
|
|
||||||
if ( existing != null ) {
|
|
||||||
if ( !QueryResultsRegion.class.isInstance( existing ) ) {
|
|
||||||
throw new IllegalStateException( "Cannot store both domain-data and query-result-data in the same region [" + regionName );
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException( "Illegal call to create QueryResultsRegion - one already existed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return regionFactory.buildQueryResultsRegion( regionName, getSessionFactory() );
|
return regionFactory.buildQueryResultsRegion( regionName, getSessionFactory() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getCacheRegionNames() {
|
public Set<String> getCacheRegionNames() {
|
||||||
return regionsByName.keySet();
|
return regionsByName.keySet();
|
||||||
|
@ -524,6 +531,10 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
|
||||||
@Override
|
@Override
|
||||||
public void evictRegion(String regionName) {
|
public void evictRegion(String regionName) {
|
||||||
getRegion( regionName ).clear();
|
getRegion( regionName ).clear();
|
||||||
|
final QueryResultsRegion queryResultsRegionWithDuplicateName = queryResultsRegionsByDuplicateName.get( regionName );
|
||||||
|
if ( queryResultsRegionWithDuplicateName != null ) {
|
||||||
|
queryResultsRegionWithDuplicateName.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -545,6 +556,9 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
|
||||||
for ( Region region : regionsByName.values() ) {
|
for ( Region region : regionsByName.values() ) {
|
||||||
region.destroy();
|
region.destroy();
|
||||||
}
|
}
|
||||||
|
for ( Region region : queryResultsRegionsByDuplicateName.values() ) {
|
||||||
|
region.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,9 @@ public interface CacheImplementor extends Service, Cache, org.hibernate.engine.s
|
||||||
void prime(Set<DomainDataRegionConfig> cacheRegionConfigs);
|
void prime(Set<DomainDataRegionConfig> cacheRegionConfigs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a cache Region by name
|
* Get a cache Region by name. If there is both a {@link DomainDataRegion}
|
||||||
|
* and a {@link QueryResultsRegion} with the specified name, then the
|
||||||
|
* {@link DomainDataRegion} will be returned.
|
||||||
*
|
*
|
||||||
* @apiNote It is only valid to call this method after {@link #prime} has
|
* @apiNote It is only valid to call this method after {@link #prime} has
|
||||||
* been performed
|
* been performed
|
||||||
|
|
Loading…
Reference in New Issue