2016-03-30 118 views
1

我是新來的spring,hibernate,c3p0 & ehcache。我正在開發一個完全使用Java Configuration的應用程序,除了web.xml。我必須在我的應用程序中使用二級緩存。所以我添加以下代碼spring + hibernate + c3p0 + ehcache java配置

import net.sf.ehcache.config.CacheConfiguration; 

import org.springframework.cache.CacheManager; 
import org.springframework.cache.annotation.CachingConfigurer; 
import org.springframework.cache.annotation.EnableCaching; 
import org.springframework.cache.ehcache.EhCacheCacheManager; 
import org.springframework.cache.interceptor.CacheErrorHandler; 
import org.springframework.cache.interceptor.CacheResolver; 
import org.springframework.cache.interceptor.KeyGenerator; 
import org.springframework.cache.interceptor.SimpleKeyGenerator; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
@EnableCaching 
public class CachingConfig implements CachingConfigurer{ 

    @Bean(destroyMethod="shutdown") 
    public net.sf.ehcache.CacheManager ehCacheManager() { 
     CacheConfiguration cacheConfiguration = new CacheConfiguration(); 
     cacheConfiguration.setName("myCacheName"); 
     cacheConfiguration.setMemoryStoreEvictionPolicy("LRU"); 
     cacheConfiguration.setMaxEntriesLocalHeap(1000); 

     net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration(); 
     config.addCache(cacheConfiguration); 

     return net.sf.ehcache.CacheManager.newInstance(config); 
    } 

    @Bean 
    @Override 
    public CacheManager cacheManager() { 
     return new EhCacheCacheManager(ehCacheManager()); 
    } 

    @Override 
    public CacheResolver cacheResolver() { 
     return null; 
    } 

    @Override 
    public CacheErrorHandler errorHandler() { 
     return null; 
    } 

    @Override 
    public KeyGenerator keyGenerator() { 
     return new SimpleKeyGenerator(); 
    } 

} 

在web.xml中我增加一條,作爲

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     ApplicationContextConfiguration 
     CachingConfig 
    </param-value> 
    </context-param> 

我ApplicationContextConfiguration是

import java.beans.PropertyVetoException; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.Properties; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; 
import org.springframework.orm.jpa.JpaVendorAdapter; 
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

import com.mchange.v2.c3p0.ComboPooledDataSource; 


@Configuration 
@EnableTransactionManagement 
public class ApplicationContextConfiguration 
{ 
     @Bean 
     public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws IOException { 
      LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); 
      entityManagerFactory.setDataSource(pooledDataSource()); 
      entityManagerFactory.setPackagesToScan(new String[] { "*" });  
      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
      entityManagerFactory.setJpaVendorAdapter(vendorAdapter); 
      entityManagerFactory.setJpaProperties(additionalProperties());  
      return entityManagerFactory; 
     } 

     @Bean 
     public ComboPooledDataSource pooledDataSource() throws IOException{ 
      ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
      Properties properties = new Properties(); 

      BufferedReader input = new BufferedReader (new InputStreamReader (getClass().getResourceAsStream("/config/hibernate.properties"))); 
      properties.load(input); 
      try { 
       dataSource.setDriverClass(properties.getProperty("hibernate.connection.driver_class")); 
      } catch (PropertyVetoException e) { 
       e.printStackTrace(); 
      } 
      dataSource.setJdbcUrl(properties.getProperty("hibernate.connection.url")); 
      dataSource.setUser(properties.getProperty("hibernate.connection.username")); 
      dataSource.setPassword(properties.getProperty("hibernate.connection.password")); 

      dataSource.setMaxPoolSize(Integer.parseInt(properties.getProperty("hibernate.c3p0.max_size"))); 
      dataSource.setMinPoolSize(Integer.parseInt(properties.getProperty("hibernate.c3p0.min_size"))); 
      dataSource.setCheckoutTimeout(Integer.parseInt(properties.getProperty("hibernate.c3p0.timeout"))); 
      dataSource.setMaxStatements(Integer.parseInt(properties.getProperty("hibernate.c3p0.max_statements"))); 
      dataSource.setIdleConnectionTestPeriod(Integer.parseInt(properties.getProperty("hibernate.c3p0.idle_test_period"))); 
      dataSource.setAcquireIncrement(Integer.parseInt(properties.getProperty("hibernate.c3p0.acquire_increment"))); 

      return dataSource; 
     } 

     @Bean 
     public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){ 
      return new PersistenceExceptionTranslationPostProcessor(); 
     } 

     Properties additionalProperties() throws IOException { 
      Properties properties = new Properties(); 
      Properties hibernateProperties = new Properties();   
      BufferedReader input = new BufferedReader (new InputStreamReader (getClass().getResourceAsStream("/config/hibernate.properties")));     
      hibernateProperties.load(input);   
      properties.setProperty("hibernate.dialect", hibernateProperties.getProperty("hibernate.dialect")); 
      return properties; 
     } 

} 

當我嘗試運行我收到以下錯誤

org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given, please either disable second level cache or set correct region factory class name to property hibernate.cache.region.factory_class (and make sure the second level cache provider, hibernate-infinispan, for example, is available in the classpath). 

I理解我必須添加

<property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property> 

但不確定在哪裏以及如何通過Java配置添加它。請有人可以在這裏幫忙。

另外,我是否需要添加以下內容?

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
<property name="hibernate.cache.use_second_level_cache">true</property> 
<property name="hibernate.cache.use_query_cache">true</property> 
+0

你的應用程序目前是否運行第二級緩存?我的意思是你能夠保存和檢索沒有二級緩存的實體嗎?你爲什麼要使用'CachingConfigurer'?因爲這與你所指的Hibernate二級緩存沒有關係? –

+0

@Madhusudana Reddy Sunnapu - 是的,我能夠沒有二級緩存檢索 –

回答

1

假設你能夠檢索實體,你只是想啓用二級緩存:

以下屬性添加在現有additionalProperties()方法。

properties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"); 
properties.setProperty("hibernate.cache.use_second_level_cache", "true"); 
properties.setProperty("hibernate.cache.use_query_cache", "true"); 

,並在entity要啓用二級緩存的地方對實體前@Cache註釋:@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

您可以刪除CachingConfig類爲具有無關啓用二級緩存爲休眠。

+0

謝謝你爲我工作 –