为什么save()不保存数据并且需要save(flush:true)?

时间:2016-12-02 06:32:09

标签: grails

RaceRegistration域已嵌入raceParticipant,而raceParticipant的字段bibNumber为Integer。

我有一个方法可以将注册的所有bibNumber归零,但是没有flush:在保存时为true,bibs的归零不起作用。围兜没有设置为null。

def nullifyBibNumbers(Long id){

        ...

        def regss = RaceRegistration.createCriteria().list(){

            eq('compositeEvent', event)

        }



        regss.each{ r ->

            r.raceParticipant.bibNumber = null
            r.save()
        }


        render "Bibs resetted!"


    }

如果我添加flush:true,则将bib设置为null。

    regss.each{ r ->

        r.raceParticipant.bibNumber = null
        r.save(flush: true)
    }

我想知道为什么你需要刷新才能将值设置为null?我猜测问题是关于我如何使用createCriteria()获取注册列表。我很欣赏我所面临的这种困境中的任何帮助。谢谢!

4 个答案:

答案 0 :(得分:1)

正如您可能已经想到的那样,save(flush: true)强制Hibernate将任何挂起的更改写入数据库。如果没有显式刷新,您将依赖Hibernate事务在事务提交时自动刷新。

只有明确同花顺序适合您的原因是因为您未在交易中调用save()

最干净的解决方法是创建Grails服务,将nullifyBibNumbers()放入其中,然后制作服务transactional。这将导致nullifyBibNumbers()被包装在一个事务中,这样您就可以在没有显式刷新的情况下使用save()

如果nullifyBibNumbers()已经在服务中,您可以将@Transactional添加到服务类,请记住它会使所有方法(可能只是公共方法?)事务性。话虽如此,您可以在方法上使用@NotTransactional来禁用事务。

答案 1 :(得分:0)

域对象中的值为null。但你猜你在数据库中讨论null吗? 没关系。这是基本的ORM。作为开发人员,您不关心何时完成刷新。通常,这将在交易结束时进行。然后,ORM将立即刷新该事务的所有更改。 它适用于事务期间所谓的第一级缓存,并尝试避免在显式请求(flush:true)或必需(事务结束)之前进入数据库。

答案 2 :(得分:0)

不使用

save(flush: true) 

该对象不会立即保留。

您可以关注documentation link并查看以下信息:

  

save方法通知持久化上下文一个实例   应该保存或更新。该对象不会被持久化   除非使用flush参数,否则立即使用。

与您面临的空问题相关,请确保满足以下条件。

  

如果验证失败且实例是,则save方法返回null   如果成功,则不会持久存在,或者实例本身。

您不需要刷新,以便将值设置为null。 flush只关心数据库的快速更新。

答案 3 :(得分:0)

好吧我使用HQL而不是域名保存修复了这个问题。仍然我会很感激为什么save()没有工作和保存(flush:true)保存数据。谢谢!

RaceRegistration.executeUpdate("update RaceRegistration set raceParticipant.bibNumber = null where compositeEvent.id = :ev", [ev: id])
相关问题