休眠二级缓存的应用程序属性

application properties for hibernate second level caching

我的 Spring 引导 application.properties 文件中有以下属性:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/coupie
spring.datasource.username=root
spring.datasource.password=password


spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

#caching

spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory

当我 运行 我的 springboot 应用程序时,它失败并显示以下堆栈跟踪:

 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 using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath.
    at org.hibernate.cache.internal.NoCachingRegionFactory.buildEntityRegion(NoCachingRegionFactory.java:66) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.cache.spi.RegionFactory.buildEntityRegion(RegionFactory.java:132) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.internal.CacheImpl.determineEntityRegionAccessStrategy(CacheImpl.java:439) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:120) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:300) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:460) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
    at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:535) ~[spring-orm-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:519) ~[spring-orm-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at com.coupie.mainapp.AppConfig.getSessionFactory(AppConfig.java:65) ~[classes/:na]

知道如何解决这个问题吗?我可以在网上找到示例,在这种情况下,我们在 hibernate.cfg.xml 中添加 hibernate.cache.region.factory_class 属性 ,但在这里我们已经在文件 .application.properties 中添加了它。

我的pom.xml相关依赖:

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency>
   <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
   </dependency>
   <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
   <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
   </dependency>
   <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->
   <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-ehcache</artifactId>
   </dependency>
</dependencies>

好吧,非常愚蠢的错误,在 Java 配置文件中创建 bean 时没有在 SessionFactory 中添加属性(在 sessionFactory bean 中添加了三个属性):

    @Configuration
    @EnableAsync
    @EnableTransactionManagement
    @EnableCaching
    public class AppConfig {

         @Autowired
            private Environment env;

          @Bean(name = "dataSource")
            public DataSource getDataSource() {
                DriverManagerDataSource dataSource = new DriverManagerDataSource();

                // See: application.properties
                dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
                dataSource.setUrl(env.getProperty("spring.datasource.url"));
                dataSource.setUsername(env.getProperty("spring.datasource.username"));
                dataSource.setPassword(env.getProperty("spring.datasource.password"));

                System.out.println("## getDataSource: " + dataSource);

                return dataSource;
            }

            @Bean(name = "sessionFactory")
            public SessionFactory getSessionFactory(DataSource dataSource) throws Exception {
                Properties properties = new Properties();

                // See: application.properties
                properties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
                properties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
                properties.put("current_session_context_class",env.getProperty("spring.jpa.properties.hibernate.current_session_context_class"));

// new props added here                     

                properties.put("hibernate.cache.use_second_level_cache", env.getProperty("spring.jpa.properties.hibernate.cache.use_second_level_cache"));
                properties.put("hibernate.cache.use_query_cache", env.getProperty("spring.jpa.properties.hibernate.cache.use_query_cache"));
                properties.put("hibernate.cache.region.factory_class", env.getProperty("spring.jpa.properties.hibernate.cache.region.factory_class"));
// new props added here              


                LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();

                // Package contain entity classes
                factoryBean.setPackagesToScan(new String[] { "" });
                factoryBean.setDataSource(dataSource);
                factoryBean.setHibernateProperties(properties);
                factoryBean.afterPropertiesSet();
                //
                SessionFactory sf = factoryBean.getObject();
                System.out.println("## getSessionFactory: " + sf);
                return sf;
            }

            @Bean(name = "transactionManager")
            public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
                HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);

                return transactionManager;
            }


            @Bean
            public Executor asyncExecutor() {
                ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
                executor.setCorePoolSize(8);
                executor.setMaxPoolSize(8);
                executor.setQueueCapacity(500);
                executor.setThreadNamePrefix("orderthread-");
                executor.initialize();
                return executor;
            }


            @Bean 
            public RestTemplate restTemplate() {
                return new RestTemplate();
            }
    }