java - Grails3 单元测试不适用于 Multi-Tenancy

标签 java hibernate grails multi-tenant specifications

我正在尝试使用 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
    }
}

最后是配置

---
#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[]

最佳答案

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

关于java - Grails3 单元测试不适用于 Multi-Tenancy ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55937752/

相关文章:

java - 如何启动 Jetty Embedded 作为 Jenkins 构建的一部分

tomcat - 如何在grails中设置tomcat特权="true"?

grails - Grails中如何改变joda--time默认的DateTime格式

Java 卡布局。多张卡中的一个组件

java - Git diff 参数可以改善源代码更改对齐吗?

java - Hibernate session 跟踪对象

java - Hibernate pojo 中 @lob 的正确 Hibernate 映射。我们正在使用 hibernate 映射。你能告诉我 @lob 注释的等效项吗

Grails Quartz - 如何将相似的两个工作组合成一个工作?

java - 即使将字符集和排序规则更改为 utf8 后,也无法将中文、俄语等字符存储到 mysql 表中

java - 在 Hibernate Search 中运行时选择分析器