Grails中奇怪的afterInsert/afterUpdate循环 [英] Weird afterInsert / afterUpdate loop in Grails
问题描述
我有一个Note
域类,保存新笔记时,我需要为其创建一个NoteEvent
,以备后代记录该笔记已创建. Note
有一个NoteEvents
的集合,每个NoteEvent
都跟踪它属于哪个Note
.
I have a Note
domain class, and when a new note is saved I need to create for it a NoteEvent
, recording for posterity that the note has been created. Note
has a collection of NoteEvents
, and each NoteEvent
keeps track of which Note
it belongs to.
Note
类:
class Note {
String noteText
Date dateCreated
static hasMany = [events : NoteEvent]
}
NoteEvent
类:
class NoteEvent {
Date dateCreated
String type
static belongsTo = [note : Note]
}
要在创建便笺时处理新的NoteEvents
的保存,我使用的是afterInsert
,因为我要在各处保存便笺实例(重复特定且耗时的特定事件-每次保存新笔记后创建代码),显然beforeInsert
尚未处理Note
的持久化实例-NoteEvent
作为其note
并没有任何内容.
To handle the saving of new NoteEvents
when a note was created, I was using afterInsert
, because I’m saving note instances all over the place (it would be repetitive and time-consuming to have specific event-creating code after each saving of a new note), and beforeInsert
obviously is not dealing with a persisted instance of Note
yet — there will be nothing for the NoteEvent
to have as its note
.
所以现在我的Note
类是:
class Note {
String noteText
Date dateCreated
static hasMany = [events : NoteEvent]
def afterInsert = {
def event = new NoteEvent(type: "CREATED")
addToEvents(event)
save()
}
}
但是,当其中一个便笺被更新时,我还需要创建一个NoteEvent
,这是混乱和沮丧和严重缺乏咖啡的地方.在便笺上附加新的更新后的" NoteEvent
更新后,我决定再次使用afterUpdate
,以避免每次需要更新Note
实例时都在应用程序中散布事件创建代码.
But I also need to create a NoteEvent
when one of these notes is updated, and this is where confusion and dismay and a significant lack of coffee come in. To attach a new "updated" NoteEvent
to a note when it was updated, I brilliantly decided to use afterUpdate
, again so as to avoid having the event creation code sprinkled all over the app whenever I needed to update a Note
instance.
现在,对于Note
,我有:
class Note {
String noteText
Date dateCreated
static hasMany = [events : NoteEvent]
def afterInsert = {
def event = new NoteEvent(type: "CREATED")
addToEvents(event)
save()
}
def afterUpdate = {
def event = new NoteEvent(type: "UPDATED")
addToEvents(event)
save()
}
}
要将新事件添加到笔记的集合中,我正在使用动态的addTo()
方法,然后需要实例的save()
.但是,在之后"事件的情况下,这是对save()
的第二次调用.因此,当我第一次保存一个新实例并调用afterInsert
时,刚刚保存的实例将立即再次保存,这会触发afterUpdate
事件,现在我有两个note事件:创建"事件从我刚刚保存便笺开始,到已创建"便导致便笺被再次保存时,出现了更新".
To add a new event to a note’s collection, I’m using the dynamic addTo()
methods, which then require a save()
of the instance. But in the case of an "after" event, this is a second call to save()
. Thus when I first save a new instance and the afterInsert
is called, the just-saved instance is immediately saved again, which causes the afterUpdate
event to be fired, and now I have two note events: the "created" one from when I just saved the note, and an "updated" one from when the "created" one caused the note to be saved again.
我不清楚在这种情况下如何使用之前"事件会有所帮助.我还能怎么做?
It’s not clear to me how using "before" events instead could help in this situation. How else can I do this?
推荐答案
您实际上可以使用beforeInsert
和beforeUpdate
方法.这是因为addTo*
方法不需要Note
作为持久实例.
You can actually use beforeInsert
and beforeUpdate
methods. This is because the addTo*
method does not require Note
to be a persisted instance.
保存Note
时将保存NoteEvent
,因为在beforeUpdate
方法中保存Note
之前先添加NoteEvent
.请查看 addTo*
文档以获取详细说明.
The NoteEvent
will save when the Note
saves because the NoteEvent
is added before the Note
is saved in the beforeUpdate
method. Check out the addTo*
docs for a longer explanation.
我能够同时获得以下两个Note
类,以确保您希望它们发挥作用.我确实遇到了一个问题,在更新Note
时将添加两个NoteEvent
对象.我可以通过确保控制器的更新方法使用的是noteInstance.save()
而不是noteInstance.save(flush:true)
来解决此问题.
I was able to get both of the following Note
classes to work how I believe you want them to. I did run into one issue where when updating Note
two NoteEvent
objects would be added. I was able to fix this by making sure that the update method of the controller was using noteInstance.save()
instead of noteInstance.save(flush:true)
.
class Note {
String noteText
Date dateCreated
static hasMany = [events : NoteEvent]
def beforeInsert = {
def event = new NoteEvent(type: "CREATED")
addToEvents(event)
}
def beforeUpdate = {
def event = new NoteEvent(type: "UPDATED")
addToEvents(event)
}
}
如果要使用更精简的版本,则addTo*
方法知道要添加的对象类型,您可以使用NoteEvent
If you want a more condensed version the addTo*
method knows what type of object is being added you can just use the Map
constructor of NoteEvent
class Note {
String noteText
Date dateCreated
static hasMany = [events : NoteEvent]
def beforeInsert = {
addToEvents(type: "CREATED")
}
def beforeUpdate = {
addToEvents(type: "UPDATED")
}
}
这篇关于Grails中奇怪的afterInsert/afterUpdate循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!