Grails3单元测试不适用于Multitenant

问题描述 投票:0回答:1

我正在尝试使用grails 3和每个租户的数据库设置一个应用程序,但是我遇到了应用程序本身的初始设置问题,我无法让单元测试工作。我写了一个空服务,并试图通过默认单元测试生成我收到以下错误

Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@10bec8db] for key [org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy@79e57f65] bound to thread [Test worker]
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@10bec8db] for key [org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy@79e57f65] bound to thread [Test worker]
    at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:542)
    at org.grails.orm.hibernate.GrailsHibernateTransactionManager.doBegin(GrailsHibernateTransactionManager.groovy:66)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
    at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)
    at test.TestService.serviceMethod_closure1(TestService.groovy)
    at groovy.lang.Closure.call(Closure.java:418)
    at groovy.lang.Closure.call(Closure.java:434)
    at grails.gorm.multitenancy.Tenants.withId_closure2$_closure6(Tenants.groovy:265)
    at org.grails.orm.hibernate.GrailsHibernateTemplate$1.doInHibernate(GrailsHibernateTemplate.java:153)
    at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:299)
    at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:243)
    at org.grails.orm.hibernate.GrailsHibernateTemplate.executeWithNewSession(GrailsHibernateTemplate.java:150)
    at org.grails.orm.hibernate.GrailsHibernateTemplate.executeWithExistingOrCreateNewSession(GrailsHibernateTemplate.java:209)
    at org.grails.orm.hibernate.AbstractHibernateDatastore.withNewSession(AbstractHibernateDatastore.java:369)
    at grails.gorm.multitenancy.Tenants.withId_closure2(Tenants.groovy:258)
    at grails.gorm.multitenancy.Tenants$CurrentTenant.withTenant(Tenants.groovy:358)
    at grails.gorm.multitenancy.Tenants.withId(Tenants.groovy:236)
    at org.grails.datastore.gorm.services.DefaultTenantService.withCurrent(DefaultTenantService.groovy:71)
    at test.TestServiceSpec.test something(TestServiceSpec.groovy:21)
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@10bec8db] for key [org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy@79e57f65] bound to thread [Test worker]
    at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:190)
    at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:516)
    ... 19 more

test.TestServiceSpec > test something FAILED
    org.springframework.transaction.CannotCreateTransactionException at TestServiceSpec.groovy:21
        Caused by: java.lang.IllegalStateException at TestServiceSpec.groovy:21
1 test completed, 1 failed
:test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.

这是我的测试代码,根据文档

package test

import grails.test.hibernate.HibernateSpec
import grails.testing.services.ServiceUnitTest
import org.grails.datastore.mapping.config.Settings
import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver

class TestServiceSpec extends HibernateSpec implements ServiceUnitTest<TestService>{

    @Override
    Map getConfiguration() {
        [(Settings.SETTING_MULTI_TENANT_RESOLVER_CLASS): SystemPropertyTenantResolver]
    }

    def setup() {
        System.setProperty(SystemPropertyTenantResolver.PROPERTY_NAME, 'audi') //
    }

    void "test something"() {
        expect:"fix me"
            def a = service.serviceMethod()
            true == true
    }
}

和我的服务代码

package test

import grails.gorm.multitenancy.CurrentTenant
import grails.gorm.transactions.Transactional

@Transactional
@CurrentTenant
class TestService {

    def serviceMethod() {
        def a= " hello"
        return a
    }
}

最后是Config

---
#tag::grails[]
grails:
#end::grails[]
    profile: web
    codegen:
        defaultPackage: example
    spring:
        transactionManagement:
            proxies: false
    #tag::gorm[]
    gorm:
    #end::gorm[]
        reactor:
            # Whether to translate GORM events into Reactor events
            # Disabled by default for performance reasons
            events: false
        #tag::multiTenancy[]
        multiTenancy:
            mode: DATABASE
            tenantResolverClass: org.grails.datastore.mapping.multitenancy.web.SessionTenantResolver
        #end::multiTenancy[]
info:
    app:
        name: '@info.app.name@'
        version: '@info.app.version@'
        grailsVersion: '@info.app.grailsVersion@'
spring:
    main:
        banner-mode: "off"
    groovy:
        template:
            check-template-location: false

# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false
    jmx:
        enabled: true

---
grails:
    mime:
        disable:
            accept:
                header:
                    userAgents:
                        - Gecko
                        - WebKit
                        - Presto
                        - Trident
        types:
            all: '*/*'
            atom: application/atom+xml
            css: text/css
            csv: text/csv
            form: application/x-www-form-urlencoded
            html:
              - text/html
              - application/xhtml+xml
            js: text/javascript
            json:
              - application/json
              - text/json
            multipartForm: multipart/form-data
            pdf: application/pdf
            rss: application/rss+xml
            text: text/plain
            hal:
              - application/hal+json
              - application/hal+xml
            xml:
              - text/xml
              - application/xml
    urlmapping:
        cache:
            maxsize: 1000
    controllers:
        defaultScope: singleton
    converters:
        encoding: UTF-8
    views:
        default:
            codec: html
        gsp:
            encoding: UTF-8
            htmlcodec: xml
            codecs:
                expression: html
                scriptlets: html
                taglib: none
                staticparts: none
endpoints:
    jmx:
        unique-names: true

---
hibernate:
    cache:
        queries: false
        use_second_level_cache: false
        use_query_cache: false

# tag::dataSources[]
dataSource:
    pooled: true
    jmxExport: true
    driverClassName: com.mysql.cj.jdbc.Driver
    username: root
    password:''
    dbCreate: create-drop
    url: jdbc:mysql://localhost:3306/master

dataSources:
    ford:
      dbCreate: create-drop
      url: jdbc:mysql://localhost:3306/child1
    audi:
      dbCreate: create-drop
      url: jdbc:mysql://localhost:3306/child2
# end::dataSources[]
java hibernate grails multi-tenant specifications
1个回答
0
投票

不用担心我终于找到了答案,我将我的所有多租户域对象打包在一个插件中以便重复使用,我在调用项目中至少需要一个域对象,它实现了多租户。测试通过的要求很奇怪,但它已经奏效了。

© www.soinside.com 2019 - 2024. All rights reserved.