【问题标题】:application properties for hibernate second level caching休眠二级缓存的应用程序属性
【发布时间】:2019-04-08 20:25:42
【问题描述】:

我的 Spring Boot 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>

【问题讨论】:

    标签: hibernate spring-boot caching ehcache application.properties


    【解决方案1】:

    好的,非常愚蠢的错误,在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();
                }
        }
    

    【讨论】:

    • spring boot中无需配置sessionFactory和transactionManager。只需设置正确的属性和自动配置即可。
    • 你能分享一个例子吗,我没有看到没有配置和应用程序属性:)
    猜你喜欢
    • 2012-03-09
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2017-07-05
    • 2011-07-08
    • 1970-01-01
    相关资源
    最近更新 更多