2323import org .hibernate .cache .cfg .spi .DomainDataRegionConfig ;
2424import org .hibernate .cache .internal .DefaultCacheKeysFactory ;
2525import org .hibernate .cache .jcache .ConfigSettings ;
26+ import org .hibernate .cache .jcache .JCacheHelper ;
2627import org .hibernate .cache .jcache .MissingCacheStrategy ;
2728import org .hibernate .cache .spi .CacheKeysFactory ;
2829import org .hibernate .cache .spi .DomainDataRegion ;
@@ -43,6 +44,12 @@ public class JCacheRegionFactory extends RegionFactoryTemplate {
4344 private volatile CacheManager cacheManager ;
4445 private volatile MissingCacheStrategy missingCacheStrategy ;
4546
47+ // need to save the classloader from Caching.getDefaultClassLoader to reset it
48+ // when this service is released again.
49+ private volatile ClassLoader oldJsr107CacheClassLoader ;
50+ // in case caches were already set up beforehand with a different configuration
51+ private volatile CacheManager preInitializedCacheManager ;
52+
4653 @ SuppressWarnings ("unused" )
4754 public JCacheRegionFactory () {
4855 this ( DefaultCacheKeysFactory .INSTANCE );
@@ -85,7 +92,8 @@ protected DomainDataStorageAccess createDomainDataStorageAccess(
8592
8693 protected Cache <Object , Object > getOrCreateCache (String unqualifiedRegionName , SessionFactoryImplementor sessionFactory ) {
8794 verifyStarted ();
88- assert !RegionNameQualifier .INSTANCE .isQualified ( unqualifiedRegionName , sessionFactory .getSessionFactoryOptions () );
95+ assert !RegionNameQualifier .INSTANCE .isQualified ( unqualifiedRegionName ,
96+ sessionFactory .getSessionFactoryOptions () );
8997
9098 final String qualifiedRegionName = RegionNameQualifier .INSTANCE .qualify (
9199 unqualifiedRegionName ,
@@ -94,6 +102,13 @@ protected Cache<Object, Object> getOrCreateCache(String unqualifiedRegionName, S
94102
95103 final Cache <Object , Object > cache = cacheManager .getCache ( qualifiedRegionName );
96104 if ( cache == null ) {
105+ if ( preInitializedCacheManager != null ) {
106+ final Cache <Object , Object > cacheFromBefore = preInitializedCacheManager .getCache (
107+ qualifiedRegionName );
108+ if ( cacheFromBefore != null ) {
109+ return cacheFromBefore ;
110+ }
111+ }
97112 return createCache ( qualifiedRegionName );
98113 }
99114 return cache ;
@@ -110,7 +125,8 @@ protected Cache<Object, Object> createCache(String regionName) {
110125 case CREATE :
111126 return cacheManager .createCache ( regionName , new MutableConfiguration <>() );
112127 case FAIL :
113- throw new CacheException ( "On-the-fly creation of JCache Cache objects is not supported [" + regionName + "]" );
128+ throw new CacheException (
129+ "On-the-fly creation of JCache Cache objects is not supported [" + regionName + "]" );
114130 default :
115131 throw new IllegalStateException ( "Unsupported missing cache strategy: " + missingCacheStrategy );
116132 }
@@ -121,7 +137,9 @@ protected boolean cacheExists(String unqualifiedRegionName, SessionFactoryImplem
121137 unqualifiedRegionName ,
122138 sessionFactory .getSessionFactoryOptions ()
123139 );
124- return cacheManager .getCache ( qualifiedRegionName ) != null ;
140+ return cacheManager .getCache ( qualifiedRegionName ) != null ||
141+ (preInitializedCacheManager != null &&
142+ preInitializedCacheManager .getCache ( qualifiedRegionName ) != null );
125143 }
126144
127145 @ Override
@@ -155,9 +173,9 @@ protected StorageAccess createTimestampsRegionStorageAccess(
155173 }
156174
157175 protected final String defaultRegionName (String regionName , SessionFactoryImplementor sessionFactory ,
158- String defaultRegionName , List <String > legacyDefaultRegionNames ) {
176+ String defaultRegionName , List <String > legacyDefaultRegionNames ) {
159177 if ( defaultRegionName .equals ( regionName )
160- && !cacheExists ( regionName , sessionFactory ) ) {
178+ && !cacheExists ( regionName , sessionFactory ) ) {
161179 // Maybe the user configured caches explicitly with legacy names; try them and use the first that exists
162180
163181 for ( String legacyDefaultRegionName : legacyDefaultRegionNames ) {
@@ -172,7 +190,6 @@ protected final String defaultRegionName(String regionName, SessionFactoryImplem
172190 }
173191
174192
175-
176193 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177194 // Lifecycle
178195
@@ -182,7 +199,14 @@ protected boolean isStarted() {
182199 }
183200
184201 @ Override
185- protected void prepareForUse (SessionFactoryOptions settings , Map <String ,Object > configValues ) {
202+ protected void prepareForUse (SessionFactoryOptions settings , Map <String , Object > configValues ) {
203+ final ClassLoader serviceClassLoader = getServiceClassLoader ( settings );
204+ if ( serviceClassLoader != null ) {
205+ preInitializedCacheManager = JCacheHelper .locateStandardCacheManager ();
206+ oldJsr107CacheClassLoader = Caching .getDefaultClassLoader ();
207+ Caching .setDefaultClassLoader ( serviceClassLoader );
208+ }
209+
186210 this .cacheManager = resolveCacheManager ( settings , configValues );
187211 if ( this .cacheManager == null ) {
188212 throw new CacheException ( "Could not locate/create CacheManager" );
@@ -192,30 +216,38 @@ protected void prepareForUse(SessionFactoryOptions settings, Map<String,Object>
192216 );
193217 }
194218
195- protected CacheManager resolveCacheManager (SessionFactoryOptions settings , Map <String ,Object > properties ) {
219+ protected CacheManager resolveCacheManager (SessionFactoryOptions settings , Map <String , Object > properties ) {
196220 final Object explicitCacheManager = properties .get ( ConfigSettings .CACHE_MANAGER );
197221 if ( explicitCacheManager != null ) {
198222 return useExplicitCacheManager ( settings , explicitCacheManager );
199223 }
200224
201- final CachingProvider cachingProvider = getCachingProvider ( properties );
225+ final ClassLoader serviceClassLoader = getServiceClassLoader ( settings );
226+ final CachingProvider cachingProvider = getCachingProvider ( properties , serviceClassLoader );
202227 final CacheManager cacheManager ;
203228 final URI cacheManagerUri = getUri ( settings , properties );
229+ final ClassLoader classLoader = getClassLoader ( cachingProvider , serviceClassLoader );
204230 if ( cacheManagerUri != null ) {
205- cacheManager = cachingProvider .getCacheManager ( cacheManagerUri , getClassLoader ( cachingProvider ) );
231+ cacheManager = cachingProvider .getCacheManager ( cacheManagerUri , classLoader );
206232 }
207233 else {
208- cacheManager = cachingProvider .getCacheManager ( cachingProvider .getDefaultURI (), getClassLoader ( cachingProvider ) );
234+ cacheManager = cachingProvider .getCacheManager ( cachingProvider .getDefaultURI (), classLoader );
209235 }
210236 return cacheManager ;
211237 }
212238
213- protected ClassLoader getClassLoader (CachingProvider cachingProvider ) {
214- // todo (5.3) : shouldn't this use Hibernate's AggregatedClassLoader?
215- return cachingProvider .getDefaultClassLoader ();
239+ private ClassLoader getServiceClassLoader (SessionFactoryOptions settings ) {
240+ final ClassLoaderService classLoaderService = settings .getServiceRegistry ()
241+ .getService ( ClassLoaderService .class );
242+ return (classLoaderService == null ) ? null :
243+ classLoaderService .workWithClassLoader ( classLoader -> classLoader );
244+ }
245+
246+ protected ClassLoader getClassLoader (CachingProvider cachingProvider , ClassLoader serviceClassLoader ) {
247+ return (serviceClassLoader != null ) ? serviceClassLoader : cachingProvider .getDefaultClassLoader ();
216248 }
217249
218- protected URI getUri (SessionFactoryOptions settings , Map <String ,Object > properties ) {
250+ protected URI getUri (SessionFactoryOptions settings , Map <String , Object > properties ) {
219251 String cacheManagerUri = getProp ( properties , ConfigSettings .CONFIG_URI );
220252 if ( cacheManagerUri == null ) {
221253 return null ;
@@ -241,14 +273,14 @@ private String getProp(Map<String,Object> properties, String prop) {
241273 return properties != null ? (String ) properties .get ( prop ) : null ;
242274 }
243275
244- protected CachingProvider getCachingProvider (final Map <String ,Object > properties ) {
276+ protected CachingProvider getCachingProvider (final Map <String ,Object > properties , ClassLoader classLoader ) {
245277 final CachingProvider cachingProvider ;
246278 final String provider = getProp ( properties , ConfigSettings .PROVIDER );
247279 if ( provider != null ) {
248- cachingProvider = Caching .getCachingProvider ( provider );
280+ cachingProvider = Caching .getCachingProvider ( provider , classLoader );
249281 }
250282 else {
251- cachingProvider = Caching .getCachingProvider ();
283+ cachingProvider = Caching .getCachingProvider ( classLoader );
252284 }
253285 return cachingProvider ;
254286 }
@@ -283,6 +315,9 @@ protected void releaseFromUse() {
283315 // - when the explicit `setting` passed to `#useExplicitCacheManager` is
284316 // a CacheManager instance
285317 cacheManager .close ();
318+ if ( oldJsr107CacheClassLoader != null ) {
319+ Caching .setDefaultClassLoader ( oldJsr107CacheClassLoader );
320+ }
286321 }
287322 finally {
288323 cacheManager = null ;
0 commit comments