这里混淆了中间状态的域对象。
所以这是一个班级:
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,因为它从未保存过,而不是具有无效价格的损坏版本?
非常感谢有人在这里解释基础设计原则 感谢。
答案 0 :(得分:2)
Hibernate没有恢复状态的过程,尽管它似乎可以,因为它为脏检查保留了数据的干净副本。调用GORM discard()
方法会沿途调用几层方法,但实际工作是在Hibernate的SessionImpl.evict(Object)
方法中完成的,只是从会话缓存中删除状态并将实例与会话解除关联,但是它对实例中的持久属性没有任何作用。如果要撤消更改,则应使用discard()
逐出实例并重新加载,例如f = Foo.get(f.id)