【问题标题】:How to create Grails domain object but do not save?如何创建 Grails 域对象但不保存?
【发布时间】:2014-12-19 17:03:41
【问题描述】:

我有一个应该创建域对象的方法。但是,如果在构建对象的过程中发生了某种情况,则该方法应该只返回而不保存对象。

给定:

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,即为什么我的对象可以找到?我认为它只会找到保存到数据库中的对象。我应该测试什么以查看我的对象是否尚未创建?

【问题讨论】:

    标签: hibernate grails grails-orm


    【解决方案1】:

    你一定是遗漏了一些东西——如果你只是创建一个实例但没有在它上面调用任何 GORM 方法,Hibernate 就无法知道它。它开始管理对象的唯一方法是通过最初的save() 调用“附加”它。没有它,它就像任何其他对象一样。

    @agusluc 所描述的是您将看到的,但不会影响您的内容。如果你加载一个以前持久化的实例并修改任何属性,在请求结束时 Hibernate 的脏检查将启动,检测到这个 attached 但未保存的实例是脏的,它会将更改推送到数据库,即使您不调用save()。在这种情况下,如果您不希望保留编辑,请通过调用discard() 将对象从会话中分离出来。这与你所看到的无关,因为你没有附加任何东西。

    可能已经存在具有 name 属性的实例。检查findByName 查询返回的其他属性,我假设您会看到它是以前持久化的实例。

    另外,这是单元测试还是集成?确保使用集成测试来实现持久性 - 单元测试模拟不是用于测试域类,它只应该用于在测试其他类型的类(例如控制器)时为域类提供 GORM 行为。

    【讨论】:

    • 你说的很对,谢谢。错误在于我在 EachWithIndex 闭包中进行更改,然后调用 return,认为不会调用闭包后的保存调用。我现在意识到闭包内的返回调用不会从包含闭包的方法返回,它只会从闭包本身返回。
    • @Burt 谢谢,拯救了我的一天。我正在搜索域类命令对象在脏时如何持久化,在 grails 文档命令对象部分中进行了搜索,但这里更清楚。我认为这应该在那里,或者我错过了什么。
    猜你喜欢
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2015-06-07
    • 2014-06-07
    • 2011-12-06
    • 2013-10-14
    • 1970-01-01
    相关资源
    最近更新 更多