3

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

  • SpringBoot 1.5.9 RELEASE
  • 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 启用了调试日志记录,并且与此对应的日志行预先添加了 <<>> 字符串,以便于定位它。

这篇文章如何解决 Hibernate 5 中的 AbstractMethodError?暗示这可能是休眠依赖关系之间的依赖关系问题。
我正在使用 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>
4

1 回答 1

1

我能够解决这个问题。
问题是我在build.gradle中声明了错误版本的hibernate-ehcache依赖项。 在 ehcache 文档中说,hibernate 能够将其用作二级缓存,hibernate-ehcache 依赖项必须与springboot 使用的hibernate-core 依赖项版本匹配。 当我在 build.gradle 中声明 ehcache 的依赖项时,我知道这一点,但我没有使用 hibernate-core 版本,而是使用 hibernate-java8 版本。 通过更正 hibernate-ehcache 版本,问题得到解决。





于 2018-11-22T16:56:46.580 回答