Grails save(flush:true)不会立即保存到数据库

时间:2015-05-23 12:21:07

标签: hibernate grails gorm

我正在使用以下代码 -

Topic topic = new Topic()
topic.name = "y u no save"
topic.save(flush:true, failOnError:true)

def promiseList = new PromiseList()
subtopicNames.each { sName ->
  promiseList << Topic.async.task {
       Subtopic subtopic = new Subtopic()
       subtopic.name = sName
       /* ... long running tasks like web service call ... */
       log.info("Topic Id : $topic.id")
       subtopic.topic = topic
       subtopic.save(flush: true, failOnError: true)
  }
}

def subtopics = promiseList.get()

我收到此错误 -

Detail: Key (topic_id)=(517333) is not present in table "topic".; nested exception is org.postgresql.util.PSQLException: ERROR: insert or update on table "subtopic" violates foreign key constraint "fkfd7d3e7098cf2d58"
  Detail: Key (topic_id)=(517333) is not present in table "topic".

当我在数据库中检查ID为517333的主题时,它实际上并不存在,而aync.task块中的日志会打印“主题ID:517333”。这里发生了什么,如何在需要时强制保存主题。

Topic - 

class Topic {
  String name
  static hasMany = [subtopics: Subtopic]
}

Subtopic - 

class Subtopic {
  String name
  static belongsTo = [topic: Topic]
}

1 个答案:

答案 0 :(得分:0)

将域实例添加到使用hasMany关系的集合中的方法是将子域添加到父类的集合中。 试试这个:

def promiseList = new PromiseList()
def topic = new Topic(name: 'main topic')
topic.save(failOnError: true, flush: true)
def subtopics = ['subtopic 1', 'subtopic 2']

subtopics.each { topicName ->
    promiseList << Topic.async.task {
        Subtopic subtopic = new Subtopic(name: topicName)
        // adding to the topic will cascade saves of the subtopics by default.
        topic.addToSubtopics(subtopic)
        /* ... long running tasks like web service call ... */
        return subtopic
    }
}

// wait for tasks to complete
def subtopicList = promiseList.get()

// Saving the topic will cascade saves of the child subtopics
topic.save(failOnError: true, flush:true)

如果您仍想按照自己的方式进行操作,可以禁用子主题的topic属性约束以允许null:

class Subtopic {
    //...
    static constraints = {
        topic nullable: true
    }
}

然后你可以这样做:

Subtopic subtopic = new Subtopic(name : topicName)
subtopic.save(flush:true)

并且,在承诺同步后:

def subtopicList = promiseList.get()
subtopicList.each {
    topic.addToSubtopics(it)
}
topic.save(failOnError: true, flush:true)