Search code examples
hibernatespring-bootcachingehcacheapplication.properties

application properties for hibernate second level caching


I have following properties in my Spring Boot application.properties file :

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

When I run my springboot application , it fails with following stacktrace :

 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]

Any idea , how to fix this ? I can find examples online where in this case we add hibernate.cache.region.factory_class property in hibernate.cfg.xml , but here we have already added that in our application.properties in file .

My pom.xml relevant dependencies :

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

Solution

  • Okay , very silly mistake , the properties were not added in the SessionFactory while creating bean in the Java config file (added three more properties in 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();
                }
        }