Vis*_*ons 1 grails hibernate grails-orm grails-domain-class
我对嵌套域类有内部要求,我希望将父关系的更新传播给子项.代码示例可以说清楚:
class Milestone {
static belongsTo = [project:Project]
static hasMany = [goals:OrgGoals, children:Milestone]
String name
Date start
Date estimatedEnd
Date achievedEnd
...
}
Run Code Online (Sandbox Code Playgroud)
当父里程碑的estimatedEnd更新时,我希望孩子的估计会自动更新相同的金额.GORM的beforeUpdate()钩子似乎是一个合乎逻辑的地方:
为了让生活更轻松,我想使用一些简单的Date算法,所以我在Milestone类中添加了以下方法:
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 }
}
}
Run Code Online (Sandbox Code Playgroud)
没有编译错误.但是当我运行以下集成测试时:
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)
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
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
Run Code Online (Sandbox Code Playgroud)
这表明beforeUpdate没有触发并执行我想要的操作.有任何想法吗?
我有一个解决方案给你.
1)更新milestone1的estimatedEnd后,在第二次保存调用中调用save(flush:true).这将强制beforeUpdate()立即触发.
2)即使在执行#1之后,您的断言仍将继续失败,因为您正在比较两个稍微不同的日期(在每个Milestone构造函数中使用单独的Date对象,因此第二个日期稍晚于/大于第一个日期.)如果你使用了相同的日期实例,例如
Date date = new Date()
def milestone1 = new Milestone(name:'test Parent milestone',
estimatedEnd: date + 10)
def milestone2 = new Milestone(name:'test child milestone',
estimatedEnd: date + 20,
)
Run Code Online (Sandbox Code Playgroud)
那么断言就会成功.在比较略有不同的日期的最佳方法方面,我将留给您下一步做什么,但您可能必须容忍毫秒级的精度差异.
希望有所帮助,
约旦
| 归档时间: |
|
| 查看次数: |
5394 次 |
| 最近记录: |