Spring MVC和EhCache无法运行

时间:2018-06-08 17:42:43

标签: spring hibernate ehcache

我正在尝试将ehcache集成到spring mvc和hibernate应用程序中,但下面不能使用的是代码。我已经按照链接 - how to use ehcache in spring mvc with hibernate进行了操作,但我仍然面临着这个问题。当我启动sertver时,这个问题就出现了。我使用的是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

2 个答案:

答案 0 :(得分:0)

根据hibernate documentation,您必须创建其他2个缓存区域

  1. org.hibernate.cache.spi.UpdateTimestampsCache:thios应该尽可能好(理想情况下永不过期)
  2. org.hibernate.cache.internal.StandardQueryCache
  3. 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();
        }
    }
    

    在我的hibernate配置中,我使用此缓存facory 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);
        }
    }
    

答案 1 :(得分:0)

我有同样的问题。通过将@EnableCaching添加到Spring Boot应用程序中,@SpringBootApplication问题得以解决。请试试。