java之SpringBoot + Hibernate + EHCache 2.X AbstractMethodError异常

myhome 阅读:65 2023-08-09 13:37:52 评论:0

我无法使用 hibernate 和 EHCache 2.X 配置 SpringBoot 项目。我正在尝试启用 hibernate 的二级缓存。
我正在使用:

  • SpringBoot 1.5.9 发布
  • hibernate 5.2.13.Final
  • EHCache 2.X(由 spring-boot-starter-cache 依赖导入)

这个项目公开了 RestAPI,当我尝试使用端点登录这个 API 的应用程序时,抛出了一个异常:

[INFO ] 2018-11-14 12:34:39.524 [main] TomcatEmbeddedServletContainer - Tomcat started on port(s): 8080 (http) 
[INFO ] 2018-11-14 12:34:39.531 [main] Application - Started Application in 14.485 seconds (JVM running for 15.155) 
nov 14, 2018 12:34:50 PM org.apache.catalina.core.ApplicationContext log 
INFO: Initializing Spring FrameworkServlet 'dispatcherServlet' 
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Filter execution threw an exception] with root cause 
java.lang.AbstractMethodError: org.hibernate.cache.ehcache.internal.nonstop.NonstopAwareEntityRegionAccessStrategy.get(Lorg/hibernate/engine/spi/SessionImplementor;Ljava/lang/Object;J)Ljava/lang/Object; 
    at org.hibernate.engine.internal.CacheHelper.fromSharedCache(CacheHelper.java:32) 
    at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4410) 
    at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:226) 
    at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:510) 
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:165) 
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69) 
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:840) 
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:822) 
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:827) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1161) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) 
    at com.sun.proxy.$Proxy151.merge(Unknown Source) 
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:511) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:520) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:505) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
    at com.sun.proxy.$Proxy184.save(Unknown Source) 
    at net.gestion_casos.service.security.UserDetailsService.updateAgent(UserDetailsService.java:66) 
    at net.gestion_casos.service.security.UserDetailsService.loadUserByUsername(UserDetailsService.java:60) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
    at com.sun.proxy.$Proxy185.loadUserByUsername(Unknown Source) 
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114) 
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144) 
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) 
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) 
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) 
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) 
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) 
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Unknown Source) 

完整的日志可以在这个链接中查看:https://ufile.io/9j69m . 我已经为 ehcache 启用了调试日志记录,并且与此对应的日志行在前面加上 <<>> 字符串以便于定位它。

此帖How to solve AbstractMethodError in Hibernate 5?暗示这可能是 hibernate 依赖项之间的依赖项问题。
我正在使用 gradle 来管理依赖项,这是我的 build.gradle,您可以在其中看到我声明的所有依赖项:

buildscript { 
    ext { 
        springBootVersion = '1.5.9.RELEASE' 
    } 
    repositories { 
        mavenCentral() 
    } 
    dependencies { 
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
    } 
} 
 
apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'org.springframework.boot' 
 
def manifestPath = "src/main/resources/Manifest.txt" 
 
Properties props = new Properties() 
props.load(new FileInputStream(String.format("%s/%s", projectDir, manifestPath))) 
 
group = 'net.integraciones.co.osi' 
version = props.getProperty("Implementation-Version") 
sourceCompatibility = 1.8 
 
jar { 
    baseName = 'service' 
    version = version 
 
    manifest { 
        from(manifestPath) 
    } 
    ant.propertyfile( 
            file: "env.properties") { 
        entry(key: "CURRENT_VERSION", value: version) 
    } 
} 
 
repositories { 
    mavenCentral() 
} 
 
dependencies { 
 
    compile('org.springframework.boot:spring-boot-starter-web:1.5.9.RELEASE') { 
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' 
    } 
 
    compile('org.springframework.boot:spring-boot-starter-security:1.5.9.RELEASE') { 
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' 
    } 
 
    // log4j2 
    compile 'org.apache.logging.log4j:log4j-api:2.5' 
    compile 'org.apache.logging.log4j:log4j-core:2.5' 
    // log4j2 bridge con slf4j 
    compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.1' 
 
    // Jackson 
    compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.7.3' 
    //compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4' 
    // support for Java 8 date/time types (specified in JSR-310 specification) 
    compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.3' 
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-hibernate5 
    compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5', version: '2.9.6' 
 
 
    // springfox-swagger2 
    compile 'io.springfox:springfox-swagger2:2.7.0' 
    compile 'io.springfox:springfox-swagger-ui:2.7.0' 
 
    // Database dependencies    
    compile (group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.10.RELEASE'){ 
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' 
    } 
    compile group: 'org.hibernate', name: 'hibernate-java8', version: '5.2.13.Final' 
    compile 'org.aspectj:aspectjweaver:1.8.9' 
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.45' 
 
    compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.14.Final' 
    compile('org.springframework.boot:spring-boot-starter-cache') { 
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' 
    }    
 
    // Apache 
    compile 'org.apache.commons:commons-lang3:3.0' 
    compile('net.sf.dozer:dozer:5.4.0') { 
        exclude group: 'org.slf4j', module: 'slf4j-log4j12' 
    } 
 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
 
    compile group: 'org.projectlombok', name: 'lombok', version: '1.16.8' 
    compile('com.google.guava:guava:21.0') 
 
    compile group: 'org.springframework.ws', name: 'spring-ws-core', version: '3.0.0.RELEASE' 
 
    compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.16' 
 
    compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.11'    
 
    //test 
    testCompile('org.springframework.boot:spring-boot-starter-test') { 
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-test-logging' 
    } 
    testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19' 
    testCompile group: 'org.apache.logging.log4j', name:'log4j-api', version: '2.5' 
    testCompile group: 'org.apache.logging.log4j', name:'log4j-core', version: '2.5' 
    testCompile group: 'org.apache.logging.log4j', name: 'log4j-web', version: '2.10.0' 
    testCompile group: 'com.h2database', name: 'h2', version: '1.4.194' 
 
} 

可以在这里查看由“gradle dependencies”命令打印的依赖关系树:https://ufile.io/ldwof

我还在springboot的application.yaml中配置了hibernate二级缓存。这是相关部分:

spring: 
  datasource: 
    name: mysql 
    driverClassName: com.mysql.jdbc.Driver 
    url: jdbc:mysql://192.168.41.211:3306/SpringBootProject?verifyServerCertificate=false&useSSL=false 
    username: root 
    password: root 
  jpa: 
    show-sql: true 
    properties: 
      javax: 
        persistence: 
          sharedCache: 
            mode: ALL 
      hibernate: 
        cache: 
          region: 
            factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory 
          use_second_level_cache: true 
        globally_quoted_identifiers: true 
    hibernate: 
      dialect: org.hibernate.dialect.MySQL5Dialect 
      ddl-auto: validate 
      naming: 
        implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl 
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 
 
server: 
  port: 8080 

我的 ehcache.xml 配置:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE ehcache> 
<ehcache  
    name="MY_CACHE"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="ehcache.xsd"  
    updateCheck="true" 
    monitoring="autodetect"  
    dynamicConfig="true"> 
 
    <diskStore path="java.io.tmpdir"/> 
 
    <defaultCache  
        maxEntriesLocalHeap="10000"  
        eternal="false" 
        timeToIdleSeconds="120"  
        timeToLiveSeconds="240"  
        maxEntriesLocalDisk="100000" 
        diskExpiryThreadIntervalSeconds="240" 
        memoryStoreEvictionPolicy="LRU"> 
        <persistence strategy="localTempSwap"/> 
    </defaultCache> 
 
    <cache name=a.project.package.Catalog" maxEntriesLocalHeap="1000" /> 
 
</ehcache> 

请您参考如下方法:

我能够解决这个问题。
问题是我在我的 build.gradle 中声明了错误版本的 hibernate-ehcache 依赖项。

在 ehcache 文档中说,hibernate 能够将其用作二级缓存,hibernate-ehcache 依赖项必须与 springboot 使用的 hibernate-core 依赖项版本 匹配。
< br/> 当我在 build.gradle 中声明对 ehcache 的依赖时,我就知道了这一点,但我没有使用 hibernate-core 版本,而是使用了 hibernate-java8 版本。

通过更正 hibernate-ehcache 版本,问题得到解决。


标签:Spring Boot
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号