Reputation: 2116
I want to configure 2nd level hibernate cache at Spring Boot microservice. And I don't want to use xml at all. Next is my example.
UserEntity.java
@Entity
@Table(name = "users")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "users")
public class UserEntity {
@Id
private long id;
@Column
private String name;
public UserEntity(long id, String name) {
this.id = id;
this.name = name;
}
// ... geters&setters
}
CacheConfig.java
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public org.springframework.cache.CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheManager());
}
private net.sf.ehcache.CacheManager ehCacheManager() {
CacheConfiguration usersCacheConfiguration = new CacheConfiguration();
usersCacheConfiguration.setName("users");
usersCacheConfiguration.eternal(false);
usersCacheConfiguration.setMaxEntriesInCache(1000);
usersCacheConfiguration.setMaxEntriesLocalDisk(0);
usersCacheConfiguration.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);
net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();
config.addCache(usersCacheConfiguration);
return net.sf.ehcache.CacheManager.create(config);
}
}
App.java
@SpringBootApplication
public class App {
public static void main(String[] args) {
new SpringApplicationBuilder(App.class)
.sources(CacheConfig.class)
.run(args);
}
}
application.properties
spring:
datasource:
url: jdbc:postgresql://localhost:5432/test
username: postgres
password: postgres
type: com.zaxxer.hikari.HikariDataSource
driverClassName: org.postgresql.Driver
jpa.hibernate.ddl-auto: update
jpa.open-in-view: false
jpa.properties.javax.persistence.sharedCache.mode: ALL
jpa.properties.hibernate:
dialect: org.hibernate.dialect.PostgreSQL9Dialect
jdbc.batch_size: 100
temp.use_jdbc_metadata_defaults: false
order_inserts: true
cache:
region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
#region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
#region_prefix: ""
use_second_level_cache: true
cache.use_query_cache: true
provider_class: org.hibernate.cache.EhCacheProvider
build.gradle
group 'com.hibernate.cache'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.0.0.RELEASE'
compile group: 'org.springframework', name: 'spring-context-support', version: '5.0.4.RELEASE'
compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.14.Final'
compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4'
}
When I run the program I see a couple of warnings indicating that entity cache configuration is not applied:
2018-03-04 23:29:48.723 WARN 8516 --- [ main] n.s.ehcache.config.ConfigurationFactory : No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/home/vitaly/.gradle/caches/modules-2/files-2.1/net.sf.ehcache/ehcache/2.10.3/cf74f9a4a049f181833b147a1d9aa62159c9d01d/ehcache-2.10.3.jar!/ehcache-failsafe.xml
2018-03-04 23:29:48.834 WARN 8516 --- [ main] o.h.c.e.AbstractEhcacheRegionFactory : HHH020003: Could not find a specific ehcache configuration for cache named [users]; using defaults.
Does anybody know what is wrong here?
Upvotes: 2
Views: 2228
Reputation: 18662
A year late but the answer to your question might require you to implement your own RegionFactory class (by extending SingletonEhCacheRegionFactory) And then set your newly created class as the factory that hibernate should use: spring.jpa.properties.hibernate.cache.region.factory_class=com.my.class https://stackoverflow.com/a/28594371/708854
Upvotes: 0
Reputation: 3830
The first warning:
2018-03-04 23:29:48.723 WARN 8516 --- [ main] n.s.ehcache.config.ConfigurationFactory : No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/home/vitaly/.gradle/caches/modules-2/files-2.1/net.sf.ehcache/ehcache/2.10.3/cf74f9a4a049f181833b147a1d9aa62159c9d01d/ehcache-2.10.3.jar!/ehcache-failsafe.xml
means that no ehcache.xml configuration was found so a default, ehcache-failsafe.xml, is used.
The second warning:
2018-03-04 23:29:48.834 WARN 8516 --- [ main] o.h.c.e.AbstractEhcacheRegionFactory : HHH020003: Could not find a specific ehcache configuration for cache named [users]; using defaults.
means that there was no configuration found for the "users" region in the cache. It is, of course, not defined in ehcache-failsafe.xml and it doesn't look like the settings in CacheConfig
are being picked up - at least not by the CacheManager
used by Hibernate.
It should be possible to solve both by adding an ehcache.xml to the classpath (in src/main/resources
), e.g.:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<cache name="users"
maxEntriesLocalHeap="500"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskExpiryThreadIntervalSeconds="1"
copyOnRead="true"
copyOnWrite="true">
<copyStrategy class="net.sf.ehcache.store.compound.ReadWriteSerializationCopyStrategy" />
</cache>
</ehcache>
(see this ehcache.xml sample for more options)
And adding the following to application.yml:
spring:
cache:
ehcache:
config: classpath:ehcache.xml
Upvotes: 1