为什么grails.gorm.autoFlush设置为true不起作用?

时间:2015-06-25 11:52:17

标签: grails gorm grails-3.0

请考虑以下代码:

class User {
    static constraints = {
        email email: true, unique: true
        token nullable: true
    }

    String email
    String password
    String token
}
@TestFor(User)
@TestMixin(DomainClassUnitTestMixin)
class UserSpec extends Specification {
    def "email should be unique"() {
        when: "twice same email"
        def user = new User(email: "test@test.com", password: "test")
        def user2 = new User(email: "test@test.com", password: "test")

        then: "saving should fail"
        user.save()
        !user2.save(failOnError: false)
    }
}

使用以下配置(部分),application.yml:

grails:
    gorm:
        failOnError: true
        autoFlush: true

为什么user2.save(failOnError: false)由于没有保存到数据库中而未返回false

跑步输出:grails test-app *UserSpec

  

businesssoftware.UserSpec>电子邮件应该是唯一的FAILED       UserSpec.groovy上的org.spockframework.runtime.ConditionNotSatisfiedError:40

当我将user.save()替换为user.save(flush: true)时, 工作。

然而https://grails.github.io/grails-doc/latest/guide/conf.html第4.1.3节的文件声称:

  

grails.gorm.autoFlush - 如果设置为true,则导致合并,保存和删除方法刷新会话,替换使用save(flush:true)显式刷新的需要。

作为参考,这是grails --version

的输出
  

| Grails版本:3.0.2
    | Groovy版本:2.4.3
    | JVM版本:1.8.0_40

而这正是我在做什么,我在这里错过了什么?

1 个答案:

答案 0 :(得分:1)

我认为autoFlush文档具有误导性。

  

grails.gorm.autoFlush - 如果设置为true,则导致合并,保存和   删除刷新会话的方法,替换显式的需要   使用save(flush:true)冲洗。

查看GormInstanceApi的save()方法和doSave()。在doSave()结束时,您将看到只有flush参数为true时刷新会话:

if (params?.flush) {
    session.flush()
}

代码中没有任何内容表明flush参数可以来自除传递给save()之外的任何其他地方。

我找不到代码来证明它,但我认为autoFlush在Hibernate会话关闭时发挥作用,例如当控制器或服务方法存在/返回时。

此外,用于Spock和JUnit的GORM实现不是真正的 GORM,因此它甚至可能不使用autoFlush配置。

我会在这里继续前行。我没有尝试过这个,但你可以能够手动刷新会话。

@TestFor(User)
@TestMixin(DomainClassUnitTestMixin)
class UserSpec extends Specification {
    def "email should be unique"() {
        when: "twice same email"
        def user = new User(email: "test@test.com", password: "test")
        def user2 = new User(email: "test@test.com", password: "test")
        simpleDatastore.currentSession.flush()

        then: "saving should fail"
        user.save()
        !user2.save(failOnError: false)
    }
}

simpleDataStore来自DomainClassUnitTestMixin