简体   繁体   中英

SpringBoot + Hibernate + EHCache 2.X AbstractMethodError exception

I'm unable to configure a SpringBoot project with hibernate and EHCache 2.X. I'm trying to enable 2nd level cache of hibernate.
I'm using:

  • SpringBoot 1.5.9 RELEASE
  • Hibernate 5.2.13.Final
  • EHCache 2.X (imported by spring-boot-starter-cache dependency)

This project exposes RestAPI and when I try to use an endpoint to login the application of this API an exception is thrown:

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

The full log can be viewed in this link: https://ufile.io/9j69m . I've enabled debug logging for ehcache and log lines corresponding to this is pre-pended with <<>> string to facilitate locating it.

This post How to solve AbstractMethodError in Hibernate 5? sugests that this could be a dependencies issue between hibernate dependencies.
I'm using gradle for managing dependecies and this is my build.gradle where you can see all my declared dependencies:

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'

}

Dependencies tree printed by "gradle dependencies" command can be viewed here: https://ufile.io/ldwof

I'd also configured hibernate second level cache in application.yaml of springboot. This is the relevant part:

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

My ehcache.xml config:

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

I was able to fix this problem.
The problem was that I was declaring a wrong version of hibernate-ehcache dependency in my build.gradle .

In the ehcache docs says that hibernate to be able to use it as a second level cache it is necesary that the hibernate-ehcache dependency match the hibernate-core dependency version used by springboot.

I knew this when I declared the dependency of ehcache in my build.gradle but instead of using the hibernate-core version I use hibernate-java8 version.

By correcting the hibernate-ehcache version the problem was solved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM