我有一个嵌套域类的内部需求,我想更新父级关系以传播给子级。一个代码示例可以说清楚:Grails挂钩到GORM beforeUpdate()
class Milestone {
static belongsTo = [project:Project]
static hasMany = [goals:OrgGoals, children:Milestone]
String name
Date start
Date estimatedEnd
Date achievedEnd
...
}
当父里程碑的estimatedEnd更新,我想孩子们的估计,自动相同的量进行更新。 GORM's beforeUpdate() hook似乎是一个合乎逻辑的地方要做到这一点:
为了使生活更轻松,我想用一些simple Date arithmetic,所以我增加了以下方法给里程碑类:
def beforeUpdate()
{
// check if an actual change has been made and the estimated end has been changed
if(this.isDirty() && this.getDirtyPropertyNames().contains("estimatedEnd"))
{
updateChildEstimates(this.estimatedEnd,this.getPersistentValue("estimatedEnd"))
}
}
private void updateChildEstimates(Date newEstimate, Date original)
{
def difference = newEstimate - original
if(difference > 0)
{
children.each{ it.estimatedEnd+= difference }
}
}
没有编译错误。但是,当我运行下面的集成测试:
void testCascadingUpdate() {
def milestone1 = new Milestone(name:'test Parent milestone',
estimatedEnd: new Date()+ 10,
)
def milestone2 = new Milestone(name:'test child milestone',
estimatedEnd: new Date()+ 20,
)
milestone1.addToChildren(milestone2)
milestone1.save()
milestone1.estimatedEnd += 10
milestone1.save()
assert milestone1.estimatedEnd != milestone2.estimatedEnd
assert milestone2.estimatedEnd == (milestone1.estimatedEnd + 10)
}
我得到:
Unit Test Results.
Designed for use with JUnit and Ant.
All Failures
Class Name Status Type Time(s)
MilestoneIntegrationTests testCascadingUpdate Failure Assertion failed: assert milestone2.estimatedEnd == (milestone1.estimatedEnd + 10) | | | | | | | | | | | Mon Jun 06 22:11:19 MST 2011 | | | | Fri May 27 22:11:19 MST 2011 | | | test Parent milestone | | false | Fri May 27 22:11:19 MST 2011 test child milestone
junit.framework.AssertionFailedError: Assertion failed:
assert milestone2.estimatedEnd == (milestone1.estimatedEnd + 10)
| | | | | |
| | | | | Mon Jun 06 22:11:19 MST 2011
| | | | Fri May 27 22:11:19 MST 2011
| | | test Parent milestone
| | false
| Fri May 27 22:11:19 MST 2011
test child milestone
at testCascadingUpdate(MilestoneIntegrationTests.groovy:43)
0.295
这表明更新前不点火,做我想要的。有任何想法吗?
为什么不使用'estimatedEnd'二传手? – 2011-05-08 11:30:04
我怀疑GORM事件可能不会在测试中执行 – 2011-05-09 08:50:33
@Victor:好点。我甚至没有考虑过这个问题,但这更有意义。 @Don:他们不会在单元测试后执行,我相信,但他们在集成测试中针对完整数据库运行。 – 2011-05-09 15:05:26