Spring启动应用程序找不到ehcache的属性工厂\u类
我正在开发一个spring应用程序(使用SpringBoot),直到今天早上它还运行得很好。我现在需要配置第二个数据源来使用两个不同的数据库(mysql+embedded h2) 我现在有两个类“MainDatabaseConfiguration”和“EmbeddedDatabaseConfiguration”,它们都提供“DataSource”类型的Bean(mainDataSource和embeddedDataSource),以及“EntityManager”、“EntityManagerFactory”和“TransactionManager”类型的关联Bean 不幸的是,应用程序初始化失败,出现以下错误:Spring启动应用程序找不到ehcache的属性工厂\u类,spring,jpa,ehcache,spring-boot,Spring,Jpa,Ehcache,Spring Boot,我正在开发一个spring应用程序(使用SpringBoot),直到今天早上它还运行得很好。我现在需要配置第二个数据源来使用两个不同的数据库(mysql+embedded h2) 我现在有两个类“MainDatabaseConfiguration”和“EmbeddedDatabaseConfiguration”,它们都提供“DataSource”类型的Bean(mainDataSource和embeddedDataSource),以及“EntityManager”、“EntityManagerF
...
Caused by: 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:83)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:363)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
...
属性“hibernate.cache.region.factory_class”存在。对于第二个数据源,我对该文件所做的唯一更改是在“spring.datasource”部分将其拆分为两部分(spring.datasource.main和spring.datasource.embedded)。
(注意:这两个数据源在我的开发环境中都是H2,但在生产环境中使用mysql)
如您所见,错误中提到的属性存在,但spring似乎无法检索到它
可能涉及错误的其他类的代码:
mainDataSourceConfiguration.java:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "mainEntityManagerFactory",
transactionManagerRef = "mainTransactionManager",
basePackages = { "com.sfr.sio.repository" })
public class MainDatabaseConfiguration extends AbstractDatabaseConfiguration implements EnvironmentAware {
/** prefix for the main datasource properties. **/
private static final String MAIN_DATASOURCE_PREFIX = "spring.datasource.main.";
/** Logger. */
private final Logger log = LoggerFactory.getLogger(MainDatabaseConfiguration.class);
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, MAIN_DATASOURCE_PREFIX);
}
/**
* Main Datasource bean creator.
* <ul>
* <li>Mysql for qualif and sfr environments</li>
* <li>h2 for dev environment</li>
* </ul>
*
* @return the datasource.
*/
@Bean(name="mainDataSource")
@Primary
public DataSource dataSource() {
log.debug("Configuring Datasource");
if (propertyResolver.getProperty(URL_PARAMETER) == null && propertyResolver.getProperty(DATABASE_NAME_PARAMETER) == null) {
log.error("Your database connection pool configuration is incorrect! The application" +
"cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles()));
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(propertyResolver.getProperty(DS_CLASS_NAME_PARAMETER));
if (propertyResolver.getProperty(URL_PARAMETER) == null || "".equals(propertyResolver.getProperty(URL_PARAMETER))) {
config.addDataSourceProperty(DATABASE_NAME_PARAMETER, propertyResolver.getProperty(DATABASE_NAME_PARAMETER));
config.addDataSourceProperty(SERVER_NAME_PARAMETER, propertyResolver.getProperty(SERVER_NAME_PARAMETER));
} else {
config.addDataSourceProperty(URL_PARAMETER, propertyResolver.getProperty(URL_PARAMETER));
}
config.addDataSourceProperty(USER_PARAM, propertyResolver.getProperty(USERNAME_PARAMETER));
config.addDataSourceProperty(PASSWORD_PARAMETER, propertyResolver.getProperty(PASSWORD_PARAMETER));
return new HikariDataSource(config);
}
/**
* @return the entity manager for the main datasource
* @see MainDatabaseConfiguration.dataSource()
*/
@Bean(name = "mainEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
/**
* @return the entity manager factory for the main datasource
* @see MainDatabaseConfiguration.dataSource()
*/
@Bean(name = "mainEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(this.dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.sfr.sio.domain");
lef.setPersistenceUnitName("mainPersistenceUnit");
lef.afterPropertiesSet();
return lef.getObject();
}
/**
* @return the transaction manager for the main datasource
* @see MainDatabaseConfiguration.dataSource()
*/
@Bean(name = "mainTransactionManager")
@Primary
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
/**
* Liquibase bean creator.
* @return the liquibase bean
*/
@Bean
@Profile(value = Constants.SPRING_PROFILE_DEVELOPMENT)
public SpringLiquibase liquibase() {
log.debug("Configuring Liquibase");
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource());
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
liquibase.setContexts("development, production");
return liquibase;
}
}
@配置
@启用事务管理
@授权代理(
entityManagerFactoryRef=“mainEntityManagerFactory”,
transactionManagerRef=“mainTransactionManager”,
basePackages={“com.sfr.sio.repository”})
公共类MainDatabaseConfiguration扩展AbstractDatabaseConfiguration实现环境感知{
/**主数据源属性的前缀**/
私有静态最终字符串MAIN\u DATASOURCE\u PREFIX=“spring.DATASOURCE.MAIN。”;
/**记录器*/
私有最终记录器log=LoggerFactory.getLogger(maindabaseconfiguration.class);
@凌驾
公共环境(环境){
this.propertyResolver=新的RelaxedPropertyResolver(环境,主数据源前缀);
}
/**
*主数据源bean创建者。
*
*用于qualif和sfr环境的Mysql
*- h2用于开发环境
*
*
*@返回数据源。
*/
@Bean(name=“maindasource”)
@初级的
公共数据源数据源(){
调试(“配置数据源”);
if(propertyResolver.getProperty(URL\u参数)==null&&propertyResolver.getProperty(数据库\u名称\u参数)==null){
log.error(“您的数据库连接池配置不正确!应用程序错误”+
“无法启动。请检查您的Spring配置文件,当前配置文件为:{}”,
toString(env.getActiveProfiles());
抛出新的ApplicationContextException(“数据库连接池配置不正确”);
}
HikariConfig config=新的HikariConfig();
config.setDataSourceClassName(propertyResolver.getProperty(DS_CLASS_NAME_参数));
if(propertyResolver.getProperty(URL_参数)==null | |?“”.equals(propertyResolver.getProperty(URL_参数))){
config.addDataSourceProperty(数据库名称参数,propertyResolver.getProperty(数据库名称参数));
config.addDataSourceProperty(SERVER_NAME_参数,propertyResolver.getProperty(SERVER_NAME_参数));
}否则{
config.addDataSourceProperty(URL_参数,propertyResolver.getProperty(URL_参数));
}
config.addDataSourceProperty(用户参数,propertyResolver.getProperty(用户名参数));
config.addDataSourceProperty(PASSWORD_参数,propertyResolver.getProperty(PASSWORD_参数));
返回新的HikariDataSource(配置);
}
/**
*@返回主数据源的实体管理器
*@请参阅MainDatabaseConfiguration.dataSource()
*/
@Bean(name=“mainEntityManager”)
公共实体管理器实体管理器(){
返回entityManagerFactory().createEntityManager();
}
/**
*@返回主数据源的实体管理器工厂
*@请参阅MainDatabaseConfiguration.dataSource()
*/
@Bean(name=“mainEntityManagerFactory”)
公共实体管理工厂实体管理工厂(){
LocalContainerEntityManagerFactoryBean lef=新的LocalContainerEntityManagerFactoryBean();
lef.setDataSource(this.dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan(“com.sfr.sio.domain”);
lef.setPersistenceUnitName(“mainPersistenceUnit”);
lef.afterPropertiesSet();
返回lef.getObject();
}
/**
*@返回主数据源的事务管理器
*@请参阅MainDatabaseConfiguration.dataSource()
*/
@Bean(name=“mainTransactionManager”)
@初级的
公共平台transactionManager transactionManager(){
返回新的JpaTransactionManager(entityManagerFactory());
}
/**
*液化豆子。
*@归还液化豆
*/
@豆子
@配置文件(值=常数。SPRING\u配置文件\u开发)
公共弹簧液化酶液化酶(){
调试(“配置Liquibase”);
SpringLiquibase=新的SpringLiquibase();
setDataSource(dataSource());
setChangeLog(“classpath:config/liquibase/master.xml”);
液化酶(“开发、生产”);
回归液化;
}
}
MainDatabaseConfiguration和EmbeddedDatabaseConfiguration之间的唯一区别是用embeddedDatasource替换mainDatasource。代码在其他方面是相同的
CacheConfiguration.java
@Configuration
@EnableCaching
@AutoConfigureAfter(value = {MetricsConfiguration.class, MainDatabaseConfiguration.class, EmbeddedDatabaseConfiguration.class})
public class CacheConfiguration {
/** Logger. */
private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);
/** Entity manager. */
@PersistenceContext(unitName="mainPersistenceUnit")
private EntityManager mainEntityManager;
/** Current environment. */
@Inject
private Environment env;
/** Metrics regitry. */
@Inject
private MetricRegistry metricRegistry;
/** Ehcache manager. */
private net.sf.ehcache.CacheManager cacheManager;
/** TTL parameter. */
private static final Integer CACHE_TIME_TO_LIVE = 3600;
/**
* Prepare destroy of the object.
*/
@PreDestroy
public void destroy() {
log.info("Remove Cache Manager metrics");
SortedSet<String> names = metricRegistry.getNames();
for (String name : names) {
metricRegistry.remove(name);
}
log.info("Closing Cache Manager");
cacheManager.shutdown();
}
/**
* Cache manager bean creator.
* @return the cache manager.
*/
@Bean
public CacheManager cacheManager() {
log.debug("Starting Ehcache");
cacheManager = net.sf.ehcache.CacheManager.create();
cacheManager.getConfiguration().setMaxBytesLocalHeap(env.getProperty("cache.ehcache.maxBytesLocalHeap", String.class, "16M"));
log.debug("Registring Ehcache Metrics gauges");
Set<EntityType<?>> entities = mainEntityManager.getMetamodel().getEntities();
for (EntityType<?> entity : entities) {
String name = entity.getName();
if ( name == null ) {
name = entity.getJavaType().getName();
}
Assert.notNull(name, "entity cannot exist without a identifier");
net.sf.ehcache.Cache cache = cacheManager.getCache(name);
if (cache != null) {
cache.getCacheConfiguration().setTimeToLiveSeconds(env.getProperty("cache.timeToLiveSeconds", Integer.class, CACHE_TIME_TO_LIVE));
net.sf.ehcache.Ehcache decoratedCache = InstrumentedEhcache.instrument(metricRegistry, cache);
cacheManager.replaceCacheWithDecoratedCache(cache, decoratedCache);
}
}
EhCacheCacheManager ehCacheManager = new EhCacheCacheManager();
ehCacheManager.setCacheManager(cacheManager);
return ehCacheManager;
}
}
@配置
@启用缓存
@AutoConfigureAfter(值={MetricsConfiguration.class,MainDatabaseConfiguration.class,EmbeddedDatabaseConfiguration.class})
公共类缓存配置{
/**记录器*/
私有最终记录器log=LoggerFactory.getLogger(CacheConfiguration.class);
/**实体经理*/
@波斯
@Configuration
@EnableCaching
@AutoConfigureAfter(value = {MetricsConfiguration.class, MainDatabaseConfiguration.class, EmbeddedDatabaseConfiguration.class})
public class CacheConfiguration {
/** Logger. */
private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);
/** Entity manager. */
@PersistenceContext(unitName="mainPersistenceUnit")
private EntityManager mainEntityManager;
/** Current environment. */
@Inject
private Environment env;
/** Metrics regitry. */
@Inject
private MetricRegistry metricRegistry;
/** Ehcache manager. */
private net.sf.ehcache.CacheManager cacheManager;
/** TTL parameter. */
private static final Integer CACHE_TIME_TO_LIVE = 3600;
/**
* Prepare destroy of the object.
*/
@PreDestroy
public void destroy() {
log.info("Remove Cache Manager metrics");
SortedSet<String> names = metricRegistry.getNames();
for (String name : names) {
metricRegistry.remove(name);
}
log.info("Closing Cache Manager");
cacheManager.shutdown();
}
/**
* Cache manager bean creator.
* @return the cache manager.
*/
@Bean
public CacheManager cacheManager() {
log.debug("Starting Ehcache");
cacheManager = net.sf.ehcache.CacheManager.create();
cacheManager.getConfiguration().setMaxBytesLocalHeap(env.getProperty("cache.ehcache.maxBytesLocalHeap", String.class, "16M"));
log.debug("Registring Ehcache Metrics gauges");
Set<EntityType<?>> entities = mainEntityManager.getMetamodel().getEntities();
for (EntityType<?> entity : entities) {
String name = entity.getName();
if ( name == null ) {
name = entity.getJavaType().getName();
}
Assert.notNull(name, "entity cannot exist without a identifier");
net.sf.ehcache.Cache cache = cacheManager.getCache(name);
if (cache != null) {
cache.getCacheConfiguration().setTimeToLiveSeconds(env.getProperty("cache.timeToLiveSeconds", Integer.class, CACHE_TIME_TO_LIVE));
net.sf.ehcache.Ehcache decoratedCache = InstrumentedEhcache.instrument(metricRegistry, cache);
cacheManager.replaceCacheWithDecoratedCache(cache, decoratedCache);
}
}
EhCacheCacheManager ehCacheManager = new EhCacheCacheManager();
ehCacheManager.setCacheManager(cacheManager);
return ehCacheManager;
}
}
@Bean
public SessionFactory sessionFactory() {
final LocalSessionFactoryBuilder localSessionFactoryBuilder = new LocalSessionFactoryBuilder(dataSource);
localSessionFactoryBuilder.scanPackages(myModelPackage);
localSessionFactoryBuilder.setProperty(Environment.CACHE_REGION_FACTORY, "org.hibernate.cache.ehcache.EhCacheRegionFactory");
return localSessionFactoryBuilder.buildSessionFactory();
}