使用缓存使用时出现NoCacheRegionFactoryAvailableException:测试时在域中只读

时间:2014-08-04 19:21:06

标签: grails

我使用的是grails 2.4.2和hibernate4 4.3.5.4。

当使用HibernateTestMixin测试服务时,如果测试使用的域包含"缓存使用的映射:readonly",则抛出org.hibernate.cache.NoCacheRegionFactoryAvailableException。

错误消息文本是"在应用程序中使用了二级缓存,但未给出属性hibernate.cache.region.factory_class;请使用hibernate.cache.region.factory_class设置禁用二级缓存或设置正确的区域工厂,并确保二级缓存提供程序(例如,hibernate-infinispan)在类路径上可用。"

factory_class在DataSource.groovy中设置。应用程序运行时没有错误,唯一的问题是运行测试时。如果缓存映射已注释掉,则测试将无错误地运行。

我还尝试设置" hibernate.cache.use_second_level_cache"在DataSource.groovy文件中为false,但该进程仍然抛出相同的异常。

Domain.groovy

package tracker

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@ToString(includeNames=true, includeFields=true, excludes='metaClass')
@EqualsAndHashCode(includes="transactionId")
class Transaction implements Serializable
{
    private static final long serialVersionUID = 1L

    Long transactionId
    Date transactionDate
    String comments

    String userId
    Date activityDate

    static mapping =
    {
        autoTimestamp false
        id column: 'transaction_id', name: 'transactionId', generator: 'sequence', params:[sequence: 'transaction_seq']
        cache usage:'read-only'
        transactionId column: 'transaction_id'
        transactionDate type: 'timestamp'
        activityDate type: 'timestamp'
    }

    static constraints =
    {
        comments(nullable:true, blank:true, maxSize: 2000)
        userId(nullable:true, blank:true, maxSize: 9)
        activityDate(nullable:true)
    }

    Map toMap()
    {
        [
                transactionId : transactionId
            ,   transactionDate : transactionDate
            ,   comments : comments
            ,   version : version
            ,   userId : userId
            ,   activityDate : activityDate
        ]
    }

}


ServiceSpec.groovy

package tracker

import grails.test.mixin.TestFor
import grails.test.mixin.TestMixin
import grails.test.mixin.gorm.Domain
import grails.test.mixin.hibernate.HibernateTestMixin
import spock.lang.Specification

@TestMixin(HibernateTestMixin)
@TestFor(ReportService)
@Domain( [Transaction, TransType])
class ReportServiceSpec extends Specification {   

    def setup() {
    }

    def cleanup() {
    }

    def createBasicTransactions() {
        new IstTransaction(
                transactionId: 1l,
                transactionDate: new Date().minus(30),
                userId: 'user1',
                activityDate: new Date()
        ).save(failOnError: true, flush: true)

        new IstTransaction(
                transactionId: 2l,
                transactionDate: new Date(),
                userId: 'user2',
                activityDate: new Date()
        ).save(failOnError: true, flush: true)
    }

    void "Test finding transactions with just basic search information"() {

        when: 'No parameter are given'
        createBasicTransactions()

        then:
        IstTransaction.count() == 2
    }
}


BuildConfig.groovy

import grails.util.Environment

grails.servlet.version = "2.5" 
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.work.dir = "target/work"
grails.project.target.level = 1.6
grails.project.source.level = 1.6

grails.project.fork = false
grails.project.dependency.resolver = "maven"
grails.project.dependency.resolution = {
    inherits("global") {
    }
    log "warn" 
    checksums true
    legacyResolve false 

    repositories {
        inherits true
        grailsCentral()
        mavenLocal()
        mavenCentral()
    }

    dependencies {
        test "org.grails:grails-datastore-test-support:1.0-grails-2.4"

        compile "commons-pool:commons-pool:1.6"
        compile "commons-collections:commons-collections:3.2.1"
    }

    plugins {
        build ":tomcat:7.0.54"

        compile ':cache:1.1.7'

        test ":code-coverage:2.0.3-1"

        runtime ":hibernate4:4.3.5.4"
    }
}


DataSource.groovy中

dataSource {
    pooled = true
    dialect = "org.hibernate.dialect.Oracle10gDialect"
    jmxExport = false
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' 
    singleSession = true
}

// environment specific settings
environments
    {
        development
            {
                dataSource
                    {
                        jndiName = "java:comp/env/jdbc/orcl"
                    }
            }
        test
            {
                dataSource
                    {
                        dbCreate = "update"
                        url = "jdbc:h2:mem:testDbBan;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
                    }
            }
        production
            {
                dataSource
                    {
                        jndiName = "java:comp/env/jdbc/orcl"
                    }
    }
}


堆栈跟踪

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'TransactionValidator': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is 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 grails.test.runtime.GrailsApplicationTestPlugin$1.initializeContext(GrailsApplicationTestPlugin.groovy:119)
    at grails.test.runtime.GrailsApplicationTestPlugin.createMainContext(GrailsApplicationTestPlugin.groovy:124)
    at grails.test.runtime.GrailsApplicationTestPlugin.initGrailsApplication(GrailsApplicationTestPlugin.groovy:98)
    at grails.test.runtime.GrailsApplicationTestPlugin.onTestEvent(GrailsApplicationTestPlugin.groovy:327)
    at grails.test.runtime.TestRuntime.deliverEvent(TestRuntime.groovy:295)
    at grails.test.runtime.TestRuntime.executeEventLoop(TestRuntime.groovy:280)
    at grails.test.runtime.TestRuntime.processEvents(TestRuntime.groovy:265)
    at grails.test.runtime.TestRuntime.doPublishEvent(TestRuntime.groovy:238)
    at grails.test.runtime.TestRuntime.publishEvent(TestRuntime.groovy:211)
    at grails.test.runtime.TestRuntime.getValue(TestRuntime.groovy:122)
    at grails.test.runtime.GrailsApplicationTestPlugin.onTestEvent(GrailsApplicationTestPlugin.groovy:320)
    at grails.test.runtime.TestRuntime.deliverEvent(TestRuntime.groovy:295)
    at grails.test.runtime.TestRuntime.processEvents(TestRuntime.groovy:264)
    at grails.test.runtime.TestRuntime.doPublishEvent(TestRuntime.groovy:248)
    at grails.test.runtime.TestRuntime.publishEvent(TestRuntime.groovy:211)
    at grails.test.runtime.TestRuntimeJunitAdapter.before(TestRuntimeJunitAdapter.groovy:107)
    at grails.test.runtime.TestRuntimeJunitAdapter$1$2.evaluate(TestRuntimeJunitAdapter.groovy:46)
    at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
    at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:84)
    at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
    at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
    at org.spockframework.runtime.extension.MethodInvocation.invokeTargetMethod(MethodInvocation.java:91)
    at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:85)
    at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1.evaluate(AbstractRuleInterceptor.java:37)
    at grails.test.runtime.TestRuntimeJunitAdapter$3$4.evaluate(TestRuntimeJunitAdapter.groovy:74)
    at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:38)
    at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:84)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is 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.
    ... 27 more
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.
    ... 27 more

1 个答案:

答案 0 :(得分:2)

这看起来像grails-datastore-test-support中的错误。我发生了类似的事情,所以我在https://jira.grails.org/browse/GRAILS-11639

打开了一个错误报告

编辑:修复了grails-datastore-test-support v.1.0.2

的错误