spring - 在 Grails 中将 Activiti 连接为 Spring Bean

标签 spring hibernate grails spock activiti

我正在尝试创建一个使用 Activiti 作为其流程引擎的 Grails 应用程序。为此,我希望将主要的 Activiti 服务类(RuntimeService、TaskService 等)连接为 Spring bean。

我相信我的接线设置正确,但是当我运行一个调用运行时服务的简单集成测试时,我收到一个错误,提示 Spring 无法打开 hibernate session (请参阅下面的 Full Stack Trace )。

更新 :我可以使用 run-app 启动应用程序,然后调用调用我的服务的 Controller 操作,一切正常。因此,Activiti 接线工作正常,只是与 Grails 集成测试 mixin 存在一些冲突。

我真的希望 Activiti 服务使用与 Grails 应用程序相同的数据源连接。我假设问题是 Activiti 正在尝试创建自己的 ConnectionHolder 实例,而 Grails 已经为集成测试设置了一个设置。

我的具体(可能是误导)问题是,如何配置 Activiti ProcessEngine 以使其使用与 Grails 应用程序相同的数据源和 hibernate 连接?

更普遍的问题是,我怎样才能最好地使 Activiti 服务对我的 Grails 应用程序可用?我看过 the Activiti plugin for grails ,它的来源帮助我走到了这一步。但是,我宁愿不使用该插件;它没有使用最新的 activiti,它的开发并不是非常活跃,而且无论如何它都不是我真正需要的。

全栈跟踪

| Failure:  start approver request(com.package.MyServiceSpec)
|  org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@7f2e1821] for key [org.springframework.jdbc.datasource.LazyConnectionDa
    at grails.test.mixin.integration.IntegrationTestMixin.initIntegrationTest(IntegrationTestMixin.groovy:58)
    at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
    at org.spockframework.runtime.extension.builtin.JUnitFixtureMethodsExtension$FixtureType$FixtureMethodInterceptor.intercept(JUnitFixtureMethodsExtension.java:145)
    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.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@7f2e1821] for key [org.springframework.jdbc.datasource.LazyConn
    ... 7 more
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@7f2e1821] for key [org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy@1b7aeb] bound to thread [main]
    ... 7 more
| Completed 1 integration test, 1 failed in 0m 1s

资源.groovy
import org.activiti.engine.ProcessEngine
import org.activiti.spring.ProcessEngineFactoryBean
import org.activiti.explorer.form.*
import org.activiti.spring.SpringProcessEngineConfiguration
import grails.util.Environment
//These imports are only needed in the test environment for building an h2 database for activiti during unit tests
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.jdbc.datasource.SimpleDriverDataSource

beans = {            
    processEngineConfig(SpringProcessEngineConfiguration) {
        dataSource = ref('dataSource')
        transactionManager = ref('transactionManager')
        databaseType = 'oracle'
        databaseSchema = 'OURSCHEMA'
        databaseSchemaUpdate = false
        jobExecutorActivate = true
    }

    processEngine(ProcessEngineFactoryBean) {
        processEngineConfiguration = ref("processEngineConfig")
    }

    runtimeService(processEngine: "getRuntimeService")
    repositoryService(processEngine: "getRepositoryService")
    taskService(processEngine: "getTaskService")
    managementService(processEngine: "getManagementService")
    historyService(processEngine: "getHistoryService")
    formService(processEngine: "getFormService")
}

服务类
class MyService {

    def foapAuthFoapService
    def processEngine
    def runtimeService
    def repositoryService
    def taskService
    def managementService
    def historyService
    def formService

    /**
    * Start the activiti process.
    * 
    */
    def startRequest(String requester, String subject, String designatedApprover) {
        runtimeService.startProcessInstanceByKey('MyProcess', ["requester": requester, "subject": subject, "designatedApprover": designatedApprover])
    }
}

斯波克测试
    def "start request"() {
        setup:
            def approverRequest = service.startRequest(requester, subject, designatedApprover)
            def variables = runtimeService.getVariables(approverRequest.id) //approverRequest.getProcessVariables()     
        expect:
            approverRequest instanceof ProcessInstance
            variables.entrySet().contailsAll(["designatedApprover": designatedApprover, "requester": requester, "subject": subject].entrySet())
        where:
            requester | subject |   designatedApprover
            "abc123"  | "def456"|   "hij789"
    }

最佳答案

我们在 Alephsa 正在维护更新到最新版本的 Activiti (5.17) 的 grails activiti 插件,我们正在努力更新到版本 6。您可以在 bintray 找到该插件。还有 grails activiti spring 安全插件。在我们的 github您可以找到源代码来指导您的工作。

问候。

关于spring - 在 Grails 中将 Activiti 连接为 Spring Bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22358785/

相关文章:

java - Spring:将转换矩阵插入 .properties 文件

java - 标准查询 ORDER BY 产生错误。这是 SQL-SERVER 的限制吗?如何在复杂的条件查询上正确排序?

grails - TagLib输出错误的编码

spring - 执行spring bean时出现问题

java - 如何在运行时管理两组属性?

Hibernate Envers - REVINFO 表不存在

java - 'One to many mapping' 场景中子实体的 findById 操作返回递归子实体。需要解决方案

jquery - Grails动态更新模板 View 而无需Ajax

grails - Grails中的URL映射

java - 使用 Spring 从 Angular 表单中恢复数据