Validate() returns false 但已保存在数据库中

Validate() returns false but it has been saved in the database

我开始使用 grails,但我遇到了一个我不理解的行为。

给定此域 class

class Team {

    String name
    Date since
    Date until

    static hasMany = [teamMembers:Player]

    static constraints = {
        name nullable: false, blank: false, unique: true
        until nullable: true
        until(validator: { val, obj ->
            val?.after(obj.since)
        })

        teamMembers maxSize: 8
        //teamMembers size: 0..8
    }
}

我想要一个集成测试来检查一个团队中的玩家实际上不能超过 8 个,所以我写了一个简化版本:

void "The team can only have up to 8 players"(){

    given:
    Player[] players = (1..9).collect {new Player(name: "Foo")}

    Team t = new Team(name:"Bar", since: new Date())

    expect:
    players.each {it.validate()}
    t.validate()

    when:

    players.each {it.save()}
    t.save()

    players.each {t.addToTeamMembers(it)}

    then:
    t.validate() == false
    t.getTeamMembers().size() == 9
    Team.get(t.id).teamMembers.size == 9
    Team.first().teamMembers.size == 9
    Team.findAll()[0].teamMembers.size == 9
    Team.findByName("Bar").teamMembers.size == 9
}

据我所知,getfind * 等访问数据库。那么为什么我的团队无法验证(预期行为)但数据库中有 9 个玩家? 我错过了什么?

注意:名称不是玩家的 PK,我已经测试了约束、大小和 maxSize。

这是一个错误吗? employees.each {t.addToTeamMembers(it)}?
因为你没有 employees 变量。

假设你想说 players.each {t.addToTeamMembers(it)}:

我想你需要在 players.each {t.addToTeamMembers(it)} 之后说 t.save() 如果你想测试坚持。

你的测试没有失败,因为你的团队规模是 9,但你实际上并没有拯救团队。

所以在 when

之前尝试保存

与此问题相关,I have found this answer from Peter Ledbrook

对此link的总结:

... as soon as you call "save()" on the Team object, it is attached to the session. Any subsequent changes to that object will then be persisted to the database including any player you add

如果这是正确的(我还没有真正尝试过),那应该可以解决问题:

void "The team can only have up to 8 players"(){

given:
   Player[] players = (1..9).collect {new Player(name: "Foo")}

   Team t = new Team(name:"Bar", since: new Date())

expect:
   players.each {it.validate()}
   t.validate()

when:
   players.each {t.addToTeamMembers(it)}
   t.save()      

then:
   !t.validate()
}

这意味着应该只保存一次团队对象(假设 Player 有一个属于团队域的 belongsTo class)。让我知道这是否有效。