Hibernate 为什么Grails中的Spock规范会导致';projectname.Event实例的标识符已从1更改为2';?

Hibernate 为什么Grails中的Spock规范会导致';projectname.Event实例的标识符已从1更改为2';?,hibernate,exception,grails,integration-testing,spock,Hibernate,Exception,Grails,Integration Testing,Spock,运行测试应用程序集成:spock会导致以下错误: 的实例的标识符 projectname.Event已从1更改为 至2;嵌套异常是 org.hibernate.HibernateException:的实例的标识符 projectname.Event已从1更改为 到2 org.springframework.orm.hibernate3.HibernateSystemException: 的实例的标识符 projectname.Event已从1更改为 至2 嵌套异常是 org.hibernate.

运行
测试应用程序集成:spock
会导致以下错误:

的实例的标识符 projectname.Event已从1更改为 至2;嵌套异常是 org.hibernate.HibernateException:的实例的标识符 projectname.Event已从1更改为 到2

org.springframework.orm.hibernate3.HibernateSystemException: 的实例的标识符 projectname.Event已从1更改为 至2

嵌套异常是 org.hibernate.HibernateException:的实例的标识符 projectname.Event已从1更改为 到2点 projectname.EventControllerSpec.save: 一 事件(EventControllerSpec.groovy:74)

原因: org.hibernate.HibernateException:的实例的标识符 projectname.Event已从1更改为 到2

  • 这个问题从何而来?
  • 如何解决这个问题?
  • [可选]是否有人可以创建标记“”

  • 来自EventControllerSpec.groovy

    def "save: an event"() {
        given: "Constraint-conform event properties"
        def eventTitle              = "Being in Beijing"
        controller.params.title     = eventTitle
        controller.params.details   = "Details"
        controller.params.location  = "Beijing"
        controller.params.startDate = "01.09.2030"
        controller.params.startTime = "20:15"
        controller.params.endDate   = "01.09.2030"
        controller.params.endTime   = "21:45"
        controller.params.publisher = getUserObject("someuser")
    
        when: "I save that event"
        def result = controller.save() // THIS IS LINE #74 AS STATED IN THE ERROR
    
        then: "The event is successfully saved and the show-view rendered"
        controller.flash.message.args.grep(eventTitle)
        redirectArgs.action             == "show"
        redirectArgs.id                 == result.eventInstance.id
    }
    
    private User getUserObject(String name) {
        def user = User.findByUsername(name)
    
        if (!user) {
            user = new User()
            user.username = name
            user.email = "${name}@example.com"
            user.pw = "barbar"
            user.pwConfirmation = "barbar"
            assert user.save()
        }
    
        user
    }
    
    def save = {
        def eventInstance = new Event()
    
        eventInstance.title     = params.title
        eventInstance.details   = params.details
        eventInstance.location  = params.location
        eventInstance.startDate = DateUtil.createDate(params.startDate, params.startTime)
        eventInstance.endDate   = DateUtil.createDate(params.endDate, params.endTime)
        eventInstance.publisher = session.user
    
        if (eventInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Event'), eventInstance.title])}"
            redirect(action: "show", id: eventInstance.id)
        }
        else {
            eventInstance.errors.each { log.warn it }
            render(view: "add", model: [eventInstance: eventInstance])
        }
    }
    
    来自EventController.groovy

    def "save: an event"() {
        given: "Constraint-conform event properties"
        def eventTitle              = "Being in Beijing"
        controller.params.title     = eventTitle
        controller.params.details   = "Details"
        controller.params.location  = "Beijing"
        controller.params.startDate = "01.09.2030"
        controller.params.startTime = "20:15"
        controller.params.endDate   = "01.09.2030"
        controller.params.endTime   = "21:45"
        controller.params.publisher = getUserObject("someuser")
    
        when: "I save that event"
        def result = controller.save() // THIS IS LINE #74 AS STATED IN THE ERROR
    
        then: "The event is successfully saved and the show-view rendered"
        controller.flash.message.args.grep(eventTitle)
        redirectArgs.action             == "show"
        redirectArgs.id                 == result.eventInstance.id
    }
    
    private User getUserObject(String name) {
        def user = User.findByUsername(name)
    
        if (!user) {
            user = new User()
            user.username = name
            user.email = "${name}@example.com"
            user.pw = "barbar"
            user.pwConfirmation = "barbar"
            assert user.save()
        }
    
        user
    }
    
    def save = {
        def eventInstance = new Event()
    
        eventInstance.title     = params.title
        eventInstance.details   = params.details
        eventInstance.location  = params.location
        eventInstance.startDate = DateUtil.createDate(params.startDate, params.startTime)
        eventInstance.endDate   = DateUtil.createDate(params.endDate, params.endTime)
        eventInstance.publisher = session.user
    
        if (eventInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Event'), eventInstance.title])}"
            redirect(action: "show", id: eventInstance.id)
        }
        else {
            eventInstance.errors.each { log.warn it }
            render(view: "add", model: [eventInstance: eventInstance])
        }
    }
    

    你的斯波克测试扩展了什么课程?它应该是
    spock.lang.Specification

    grails.plugin.spock.IntegrationSpec
    而不是为单元测试设计的
    grails.plugin.spock.ControllerSpec

    如果您可以发布事件的定义,可能会有所帮助。另外,您使用什么数据库进行集成测试?我尝试了MySQL和HSQLDB;你认为域类的定义对这一点有什么影响?嗨,Peter,我在开发的后期将规范从单元转移到了集成(因此仍然扩展了ControllerSpec)。现在,按照您的提示并更改为IntegrationSpec(或spock.lang.Specification)将删除对“controller”的访问(没有这样的属性:controller for class:corilla.EventControllerSpec)。我试过几种方法来找回它(新的…(),Mock()),但显然我做错了什么…正确。IntegrationSpec没有“控制器”属性。您必须自己实例化控制器并连接到任何服务或其他Springbean中。这是集成测试的标准实践。顺便问一下,为什么要对控制器使用集成测试?它的价值通常很低,而访问数据库的服务的集成测试的价值通常较高。