1. 程式人生 > >SpringMVC4.3+ hibernate5 整合EhCache 二級快取 給予java-config

SpringMVC4.3+ hibernate5 整合EhCache 二級快取 給予java-config

   1. sessionFactory 的配置
@Configuration
//啟用註解事務管理,使用CGLib代理
@EnableTransactionManagement(proxyTargetClass = true)
@Import({DataSourceConfig.class})
public class DaoConfig {

    private static final Logger logger = Logger.getLogger(DaoConfig.class);
    @Resource(name = "dataSource")
    public DataSource dataSource
; @Value("${hibernate.dialect}") String hibernate_dialect; @Value("${hibernate.show_sql}") String hibernate_show_sql; /** * 描述 : <負責解析資原始檔>. <br> * <p> * <這個類必須有,而且必須宣告為static,否則不能正常解析> * </p> * * @return */ @Bean public static
PropertySourcesPlaceholderConfigurer placehodlerConfigurer() { logger.info("PropertySourcesPlaceholderConfigurer"); return new PropertySourcesPlaceholderConfigurer(); } @Bean(name = "hibernateDAO") public CP_Hibernate4DAOImpl hibernate4Dao() { logger.info("hibernateDAO"
); CP_Hibernate4DAOImpl dao = new CP_Hibernate4DAOImpl(); dao.setSessionFactory(localSessionFactoryBean().getObject()); return dao; } @Bean(name = "sessionFactory") public LocalSessionFactoryBean localSessionFactoryBean() { logger.info("sessionFactory"); LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(dataSource); String[] packagesToScan = new String[]{"com.mvc.entity"}; sessionFactory.setPackagesToScan(packagesToScan); Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.dialect", hibernate_dialect); hibernateProperties.setProperty("hibernate.show_sql", hibernate_show_sql); hibernateProperties.setProperty( "hibernate.current_session_context_class", "org.springframework.orm.hibernate5.SpringSessionContext"); // 二級快取 hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "true"); hibernateProperties.setProperty("hibernate.cache.use_query_cache", "true"); // hibernateProperties.setProperty("hibernate.cache.provider_class", // "org.hibernate.cache.EhCacheProvider"); // hibernateProperties.setProperty("hibernate.cache.region.factory_class", // "org.hibernate.cache.ehcache.EhCacheRegionFactory"); hibernateProperties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"); sessionFactory.setHibernateProperties(hibernateProperties); return sessionFactory; }
2. datasource配置
@Configuration
//db 配置檔案
@PropertySource({"classpath:config/properties/db.properties"})
public class DataSourceConfig {
    private static final Logger logger = Logger.getLogger(DataSourceConfig.class);
    /*
     *db 配置
     */
@Value("${jdbc.driver}")
    String driverClass;
    @Value("${jdbc.url}")
    String url;
    @Value("${jdbc.username}")
    String userName;
    @Value("${jdbc.password}")
    String passWord;

    @Bean(name = "dataSource")
    public DataSource dataSource() {
        logger.info("DataSource");
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(passWord);
        return dataSource;
    }
}

//  ehcache 配置配置
@Configuration
@EnableCaching//<!-- 啟用快取註解 --> <cache:annotation-driven cache-manager="cacheManager" />
public class CachingConfig {
    private static final Logger logger = Logger.getLogger(CachingConfig.class);


    @Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource(
            "config/ehcache.xml"));
        ehCacheManagerFactoryBean.setShared(true);
        return ehCacheManagerFactoryBean;
    }

    @Bean
public CacheManager cacheManager() {
        logger.info("EhCacheCacheManager");
        EhCacheCacheManager cacheManager = new EhCacheCacheManager();
        cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
        return cacheManager;
    }
}
實體配置:
@Entity
@Table(name="UserInfo")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class UserInfo {
}整合時發生以下錯誤:
1 . Unable to create requested service [org.hibernate.cache.spi.RegionFactory]
原因: hibernate.cache.region.factory_class 屬性沒有配置, 這個屬於hibernate版本4以上的配置, 3版本配置 hibernate.cache.provider_class
2. Another unnamed CacheManager already exists in the same VM.
原因  ehcache在2.5以後,CacheManager使用了Singleton,這樣在建立多個CacheManager時就會產生上述錯誤。ehCacheManagerFactoryBean.setShared(true);
於是我嘗試找到ehcache2.5 以前的jar包進行嘗試,對於gradle 自動下載compile("org.hibernate:hibernate-ehcache:5.1.7.Final") 自動下載hibernate依賴會連
同ehcache也自動關聯一個版本, 所以使用本地jar載入,建立src 同級目錄,在build.gradle 中新增 compile fileTree(dir:'libs',include:['*.jar']), 去掉ehCacheManagerFactoryBean.setShare(true),
同時還要載入 
    compile("org.apache.logging.log4j:log4j-core:2.8.2")
    compile("log4j:log4j:1.2.17")
這兩個日誌依賴,才能正常執行