spring + hibernate + c3p0 + ehcache java configuration



我对spring、hibernate、c3p0&ehcache。除了web.xml之外,我正在开发一个完全使用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).

我知道我必须添加

<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>

假设您能够检索实体,并且只想启用二级缓存:

在现有的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类,因为这与为Hibernate启用二级缓存无关。

最新更新