Spring MVC 和 EhCache 不工作
Spring MVC and EhCache is not working
我正在尝试将 ehcache 集成到 spring mvc 和 hibernate 应用程序中,但是下面的代码无法正常工作。我遵循了 link - how to use ehcache in spring mvc with hibernate 但我仍然面临问题。当我启动服务器时,这个问题就来了。我正在使用 spring 5.0.5
springmvc.xml
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan">
<beans:array>
<beans:value>com.kalavakuri.springmvcandorm</beans:value>
</beans:array>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">${hibernate.dialect}</beans:prop>
<beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">true</beans:prop>
<beans:prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</beans:prop>
<beans:prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">true</beans:prop>
<!-- <beans:prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</beans:prop> -->
</beans:props>
</beans:property>
</beans:bean>
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir" />
<!--defaultCache eternal="false" maxElementsInMemory="1000" maxElementsOnDisk="10000"
overflowToDisk="true" diskPersistent="true" timeToLiveSeconds="300" statistics="true"
copyOnWrite="true" / -->
<cache name="student" maxElementsInMemory="100000"
eternal="true" overflowToDisk="false" memoryStoreEvictionPolicy="LFU"
statistics="true" timeToLiveSeconds="3600" />
</ehcache>
I am getting below error:
Caused by: org.hibernate.cache.CacheException: On-the-fly creation of JCache Cache objects is not supported [org.hibernate.cache.spi.TimestampsRegion]
at org.hibernate.cache.ehcache.internal.EhcacheRegionFactory.createCache(EhcacheRegionFactory.java:106)
at org.hibernate.cache.ehcache.internal.EhcacheRegionFactory.getOrCreateCache(EhcacheRegionFactory.java:100)
at org.hibernate.cache.ehcache.internal.EhcacheRegionFactory.createTimestampsRegionStorageAccess(EhcacheRegionFactory.java:86)
at org.hibernate.cache.spi.support.RegionFactoryTemplate.buildTimestampsRegion(RegionFactoryTemplate.java:70)
at org.hibernate.cache.internal.EnabledCaching.<init>(EnabledCaching.java:80)
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:33)
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:24)
at org.hibernate.service.spi.SessionFactoryServiceInitiator.initiateService(SessionFactoryServiceInitiator.java:30)
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:68)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 99 more
根据 hibernate documentation 你必须创建其他 2 个缓存区域
- org.hibernate.cache.spi.UpdateTimestampsCache: thios 应该尽可能大(最好永不过期)
- org.hibernate.cache.internal.StandardQueryCache
Hibernate 无法即时将它们打包(尤其是第一个)
实际上,通过使用 ehcahe 3 和 hibernate 5,我使用了这个配置:
@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport
{
@Autowired
private Environment env;
@Bean("cacheManager")
@Override
public org.springframework.cache.CacheManager cacheManager()
{
return new JCacheCacheManager(createCacheManager());
}
private CacheManager createCacheManager()
{
long dimensioneCache = new Long(env.getProperty("arca.context.cache.size"));
long ttlMillisecondi = new Long(env.getProperty("arca.context.cache.ttl"));
org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration = CacheConfigurationBuilder.
newCacheConfigurationBuilder(Object.class, Object.class,
ResourcePoolsBuilder.heap(dimensioneCache)
).withExpiry(Expirations.timeToLiveExpiration(new org.ehcache.expiry.Duration(ttlMillisecondi, TimeUnit.MILLISECONDS))).build();
Map<String, org.ehcache.config.CacheConfiguration<?, ?>> caches = createCacheConfigurations(cacheConfiguration);
//Creo la cache di hibernate org.hibernate.cache.spi.UpdateTimestampsCache.
//Dalla documentazione di hibernate https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#caching
ResourcePoolsBuilder rpb = ResourcePoolsBuilder.heap(dimensioneCache*1000000);
org.ehcache.config.CacheConfiguration<Object, Object> eternalCacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, rpb).withExpiry(Expirations.noExpiration()).build();
caches.put("org.hibernate.cache.spi.UpdateTimestampsCache", eternalCacheConfiguration);
EhcacheCachingProvider provider = getCachingProvider();
DefaultConfiguration configuration = new DefaultConfiguration(caches, provider.getDefaultClassLoader());
CacheManager result = provider.getCacheManager(provider.getDefaultURI(), configuration);
return result;
}
private Map<String, org.ehcache.config.CacheConfiguration<?, ?>> createCacheConfigurations(org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration)
{
Map<String, org.ehcache.config.CacheConfiguration<?, ?>> caches = new HashMap<>();
// I'm searcing for all objects with @Entity annotation in order to create cache regions
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
for (BeanDefinition bd : scanner.findCandidateComponents("it.test.models"))
{
String className = bd.getBeanClassName();
caches.put(className, cacheConfiguration);
}
//org.hibernate.cache.internal.StandardQueryCache creation
caches.put("org.hibernate.cache.internal.StandardQueryCache", cacheConfiguration);
return caches;
}
private EhcacheCachingProvider getCachingProvider()
{
return (EhcacheCachingProvider) Caching.getCachingProvider();
}
}
在我的休眠配置中,我使用了这个缓存工厂it.olegna.tests.hibernate.cache.config.JCacheRegionFactory
它的代码如下:
public class JCacheRegionFactory extends org.hibernate.cache.jcache.JCacheRegionFactory
{
private static final long serialVersionUID = 1021281213463444167L;
@Override
protected Cache<Object, Object> createCache(String regionName, Properties properties, CacheDataDescription metadata)
{
throw new IllegalArgumentException("Unknown hibernate cache: " + regionName);
}
}
我遇到了同样的问题。通过将@EnableCaching 添加到spring 引导应用程序@SpringBootApplication 问题得到解决。请试试。
我正在尝试将 ehcache 集成到 spring mvc 和 hibernate 应用程序中,但是下面的代码无法正常工作。我遵循了 link - how to use ehcache in spring mvc with hibernate 但我仍然面临问题。当我启动服务器时,这个问题就来了。我正在使用 spring 5.0.5
springmvc.xml
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan">
<beans:array>
<beans:value>com.kalavakuri.springmvcandorm</beans:value>
</beans:array>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">${hibernate.dialect}</beans:prop>
<beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">true</beans:prop>
<beans:prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</beans:prop>
<beans:prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">true</beans:prop>
<!-- <beans:prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</beans:prop> -->
</beans:props>
</beans:property>
</beans:bean>
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir" />
<!--defaultCache eternal="false" maxElementsInMemory="1000" maxElementsOnDisk="10000"
overflowToDisk="true" diskPersistent="true" timeToLiveSeconds="300" statistics="true"
copyOnWrite="true" / -->
<cache name="student" maxElementsInMemory="100000"
eternal="true" overflowToDisk="false" memoryStoreEvictionPolicy="LFU"
statistics="true" timeToLiveSeconds="3600" />
</ehcache>
I am getting below error:
Caused by: org.hibernate.cache.CacheException: On-the-fly creation of JCache Cache objects is not supported [org.hibernate.cache.spi.TimestampsRegion]
at org.hibernate.cache.ehcache.internal.EhcacheRegionFactory.createCache(EhcacheRegionFactory.java:106)
at org.hibernate.cache.ehcache.internal.EhcacheRegionFactory.getOrCreateCache(EhcacheRegionFactory.java:100)
at org.hibernate.cache.ehcache.internal.EhcacheRegionFactory.createTimestampsRegionStorageAccess(EhcacheRegionFactory.java:86)
at org.hibernate.cache.spi.support.RegionFactoryTemplate.buildTimestampsRegion(RegionFactoryTemplate.java:70)
at org.hibernate.cache.internal.EnabledCaching.<init>(EnabledCaching.java:80)
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:33)
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:24)
at org.hibernate.service.spi.SessionFactoryServiceInitiator.initiateService(SessionFactoryServiceInitiator.java:30)
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:68)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 99 more
根据 hibernate documentation 你必须创建其他 2 个缓存区域
- org.hibernate.cache.spi.UpdateTimestampsCache: thios 应该尽可能大(最好永不过期)
- org.hibernate.cache.internal.StandardQueryCache
Hibernate 无法即时将它们打包(尤其是第一个)
实际上,通过使用 ehcahe 3 和 hibernate 5,我使用了这个配置:
@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport
{
@Autowired
private Environment env;
@Bean("cacheManager")
@Override
public org.springframework.cache.CacheManager cacheManager()
{
return new JCacheCacheManager(createCacheManager());
}
private CacheManager createCacheManager()
{
long dimensioneCache = new Long(env.getProperty("arca.context.cache.size"));
long ttlMillisecondi = new Long(env.getProperty("arca.context.cache.ttl"));
org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration = CacheConfigurationBuilder.
newCacheConfigurationBuilder(Object.class, Object.class,
ResourcePoolsBuilder.heap(dimensioneCache)
).withExpiry(Expirations.timeToLiveExpiration(new org.ehcache.expiry.Duration(ttlMillisecondi, TimeUnit.MILLISECONDS))).build();
Map<String, org.ehcache.config.CacheConfiguration<?, ?>> caches = createCacheConfigurations(cacheConfiguration);
//Creo la cache di hibernate org.hibernate.cache.spi.UpdateTimestampsCache.
//Dalla documentazione di hibernate https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#caching
ResourcePoolsBuilder rpb = ResourcePoolsBuilder.heap(dimensioneCache*1000000);
org.ehcache.config.CacheConfiguration<Object, Object> eternalCacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, rpb).withExpiry(Expirations.noExpiration()).build();
caches.put("org.hibernate.cache.spi.UpdateTimestampsCache", eternalCacheConfiguration);
EhcacheCachingProvider provider = getCachingProvider();
DefaultConfiguration configuration = new DefaultConfiguration(caches, provider.getDefaultClassLoader());
CacheManager result = provider.getCacheManager(provider.getDefaultURI(), configuration);
return result;
}
private Map<String, org.ehcache.config.CacheConfiguration<?, ?>> createCacheConfigurations(org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration)
{
Map<String, org.ehcache.config.CacheConfiguration<?, ?>> caches = new HashMap<>();
// I'm searcing for all objects with @Entity annotation in order to create cache regions
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
for (BeanDefinition bd : scanner.findCandidateComponents("it.test.models"))
{
String className = bd.getBeanClassName();
caches.put(className, cacheConfiguration);
}
//org.hibernate.cache.internal.StandardQueryCache creation
caches.put("org.hibernate.cache.internal.StandardQueryCache", cacheConfiguration);
return caches;
}
private EhcacheCachingProvider getCachingProvider()
{
return (EhcacheCachingProvider) Caching.getCachingProvider();
}
}
在我的休眠配置中,我使用了这个缓存工厂it.olegna.tests.hibernate.cache.config.JCacheRegionFactory
它的代码如下:
public class JCacheRegionFactory extends org.hibernate.cache.jcache.JCacheRegionFactory
{
private static final long serialVersionUID = 1021281213463444167L;
@Override
protected Cache<Object, Object> createCache(String regionName, Properties properties, CacheDataDescription metadata)
{
throw new IllegalArgumentException("Unknown hibernate cache: " + regionName);
}
}
我遇到了同样的问题。通过将@EnableCaching 添加到spring 引导应用程序@SpringBootApplication 问题得到解决。请试试。