java.lang.NoSuchMethodErrorSetup 关于使用 EhCache 的 Hibernate 缓存
java.lang.NoSuchMethodErrorSetup on Hibernate cache with EhCache
我试图在 Hibernate 5.2.4+ Spring 4.3.7 上向我的项目添加缓存,但在调用 getCurrentSession().get(entityClass, id)
方法时出现错误:
java.lang.NoSuchMethodError: org.hibernate.cache.internal.DefaultCacheKeysFactory.staticCreateEntityKey(Ljava/lang/Object;Lorg/hibernate/persister/entity/EntityPersister;Lorg/hibernate/engine/spi/SessionFactoryImplementor;Ljava/lang/String;)Ljava/lang/Object;
休眠配置:
@Configuration
@EnableTransactionManagement
@PropertySource(value = {"classpath:hibernate.properties"})
public class HibernateConfig {
private Environment environment;
@Autowired
HibernateConfig(Environment environment){
this.environment = environment;
}
@Bean
public LocalSessionFactoryBean sessionFactory(){
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(dataSource());
localSessionFactoryBean.setPackagesToScan("io.delivery.entity");
localSessionFactoryBean.setHibernateProperties(hibernateProperties());
return localSessionFactoryBean;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getProperty("hibernate.driverClass"));
dataSource.setUrl(environment.getProperty("hibernate.url"));
dataSource.setUsername(environment.getProperty("hibernate.username"));
dataSource.setPassword(environment.getProperty("hibernate.password"));
return dataSource;
}
private Properties hibernateProperties(){
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
properties.put("show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.cache.region.factory_class", environment.getRequiredProperty("hibernate.cache.region.factory_class"));
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
hibernate.properties:
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
pom.xml:
<!-- hibernate-jcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- hibernate-ehcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.4</version>
</dependency>
我做错了什么?
Hibernate 5.2 以两种方式支持 Ehcache。 hibernate-ehcache
原生支持 Ehcache 2(您正在使用的)。通过 JCache 支持 Ehcache 3。
假设您继续使用 Ehcache 2(与您选择的区域工厂匹配),您应该删除 hibernate-jcache
。
然后,你需要确定你已经导入了LocalSessionFactoryBean
的Hibernate 5版本。
我做到了,而且效果很好。我的进口:
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
我的 pom(jcache 还在,但不需要):
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.195</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- hibernate-jcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- hibernate-ehcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.4</version>
</dependency>
我和hibernate-core有版本冲突!将 5.2.4.Final 添加到 pom.xml 中的属性并在所有休眠依赖项中引用 ${hibernate.version} 解决了问题。
我试图在 Hibernate 5.2.4+ Spring 4.3.7 上向我的项目添加缓存,但在调用 getCurrentSession().get(entityClass, id)
方法时出现错误:
java.lang.NoSuchMethodError: org.hibernate.cache.internal.DefaultCacheKeysFactory.staticCreateEntityKey(Ljava/lang/Object;Lorg/hibernate/persister/entity/EntityPersister;Lorg/hibernate/engine/spi/SessionFactoryImplementor;Ljava/lang/String;)Ljava/lang/Object;
休眠配置:
@Configuration
@EnableTransactionManagement
@PropertySource(value = {"classpath:hibernate.properties"})
public class HibernateConfig {
private Environment environment;
@Autowired
HibernateConfig(Environment environment){
this.environment = environment;
}
@Bean
public LocalSessionFactoryBean sessionFactory(){
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(dataSource());
localSessionFactoryBean.setPackagesToScan("io.delivery.entity");
localSessionFactoryBean.setHibernateProperties(hibernateProperties());
return localSessionFactoryBean;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getProperty("hibernate.driverClass"));
dataSource.setUrl(environment.getProperty("hibernate.url"));
dataSource.setUsername(environment.getProperty("hibernate.username"));
dataSource.setPassword(environment.getProperty("hibernate.password"));
return dataSource;
}
private Properties hibernateProperties(){
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
properties.put("show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.cache.region.factory_class", environment.getRequiredProperty("hibernate.cache.region.factory_class"));
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
hibernate.properties:
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
pom.xml:
<!-- hibernate-jcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- hibernate-ehcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.4</version>
</dependency>
我做错了什么?
Hibernate 5.2 以两种方式支持 Ehcache。 hibernate-ehcache
原生支持 Ehcache 2(您正在使用的)。通过 JCache 支持 Ehcache 3。
假设您继续使用 Ehcache 2(与您选择的区域工厂匹配),您应该删除 hibernate-jcache
。
然后,你需要确定你已经导入了LocalSessionFactoryBean
的Hibernate 5版本。
我做到了,而且效果很好。我的进口:
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
我的 pom(jcache 还在,但不需要):
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.195</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- hibernate-jcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- hibernate-ehcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.4</version>
</dependency>
我和hibernate-core有版本冲突!将 5.2.4.Final 添加到 pom.xml 中的属性并在所有休眠依赖项中引用 ${hibernate.version} 解决了问题。