丢弃后,为什么未刷新的域对象不会恢复为“已保存”状态?我可以获得“干净”的版本吗?

时间:2014-12-02 07:14:20

标签: grails gorm grails-2.0 grails-domain-class

这里混淆了中间状态的域对象。

所以这是一个班级:

class Foo {
    Double price
    String name
    Date creationDate = new Date()

    static constraints = {
        price min: 50D
        creationDate nullable: false
    }
}

这个测试用例:

@TestFor(Foo)
class FooSpec extends Specification {
   void "test creation and constraints"() {
        when: "I create a Foo within constraints"
            Foo f= new Foo(price: 60D, name: "FooBar")
        then:  "It validates and saves"
            f.validate()
            f.save()
        when: "I make that foo invalid"
            f.price=49D
        then: "It no longer validates"
            !f.validate()
        when: "I discard the changes since the last save"
            f.discard()
        then: "it validates again"
            f.validate()                //TEST FAILS HERE
    }
}

所以这个测试在最后一次验证时失败了,因为f.discard()似乎没有将f恢复为其保存的"州。关于grails文档的注释似乎表明这是打算(至少对我来说非常混乱)行为。所有"丢弃"将它标记为不被持久化(如果它不通过约束它就不会这样,所以在这样的情况下,我猜它没有做任何事情?)我认为刷新可能会让我保存状态,甚至Foo.get([id])但这些都不起作用。 Foo.get获取了损坏的版本,f.refresh显然抛出了一个nullPointer因为creationDate为null而且它不应该是。

所有这一切都令人困惑,而且似乎没有办法在没有被冲洗的情况下回到对象的已保存状态。这是真的吗?哪种问题提出了问题"在什么方面是对象"保存?"

这似乎意味着我想要确保我确实从数据库中读取而不是缓存,如果我想确定我获得了对象的有效持久状态,\不是一些可能被破坏的中间状态。

相关问题 - 不确定本地缓存的范围 - 是否仅限于会话?因此,如果我开始另一个会话并检索该ID,我会得到一个null,因为它从未保存过,而不是具有无效价格的损坏版本?

非常感谢有人在这里解释基础设计原则 感谢。

1 个答案:

答案 0 :(得分:2)

Hibernate没有恢复状态的过程,尽管它似乎可以,因为它为脏检查保留了数据的干净副本。调用GORM discard()方法会沿途调用几层方法,但实际工作是在Hibernate的SessionImpl.evict(Object)方法中完成的,只是从会话缓存中删除状态并将实例与会话解除关联,但是它对实例中的持久属性没有任何作用。如果要撤消更改,则应使用discard()逐出实例并重新加载,例如f = Foo.get(f.id)