我有一个应该创建域对象的方法。但是,如果在构建对象的过程中发生了某种情况,该方法应该只返回而不保存对象。
给定:
class SomeDomainObjectClass {
String name
}
class DomCreatorService {
def createDom() {
SomeDomainObjectClass obj = new SomeDomainObjectClass(name: "name")
// do some processing here and realise we don't want to save the object to the database
if (!dontWannaSave) {
obj.save(flush: true)
}
}
}
在我的测试中(服务是 DomCreatorService 的实例):
expect: "it doesn't exist at first"
SomeDomainObjectClass.findByName("name") == null
when: "we attempt to create the object under conditions that mean it shouldn't be saved"
// assume that my test conditions will mean dontWannaSave == true and we shouldn't save
service.createDom()
then: "we shouldn't be able to find it and it shouldn't exist in the database"
// check that we still haven't created an instance
SomeDomainObjectClass.findByName("name") == null
我的最后一行失败了。为什么最后一个 findByName 返回 true,即为什么可以找到我的对象?我以为它只会找到保存到数据库中的对象。我应该测试什么以查看我的对象是否尚未创建?
最佳答案
您一定遗漏了一些东西——如果您只是创建一个实例但不对其调用任何 GORM 方法,Hibernate 就无法知道它。它开始管理对象的唯一方法是通过初始 save()
调用“附加”它。没有它,它就像任何其他对象一样。
您将看到的是@agusluc 所描述的,但在这里不会影响您。如果您加载以前持久化的实例并修改任何属性,在请求结束时,Hibernate 的脏检查将启动,检测到这个附加但未保存的实例是脏的,它会将更改推送到数据库,即使您不调用 save()
。在这种情况下,如果您不希望编辑持续存在,请通过调用 discard()
从 session 中分离对象。这与您所看到的无关,因为您没有附加任何东西。
可能已经有一个具有该 name
属性的实例。检查 findByName
查询返回的其他属性,我假设您会看到它是以前持久化的实例。
此外,这是单元测试还是集成?请务必使用集成测试来实现持久性 - 单元测试模拟不适用于测试域类,它只应该用于在测试其他类型的类(例如 Controller )时为域类提供 GORM 行为。
关于hibernate - 如何创建 Grails 域对象但不保存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27570653/