我对嵌套域类有一个内部要求,我想将对父级关系的更新传播到子级。一个代码示例可以清楚地表明:

class Milestone { 
    static belongsTo = [project:Project] 
    static hasMany = [goals:OrgGoals, children:Milestone] 
    String name 
    Date start 
    Date estimatedEnd 
    Date achievedEnd 
    ... 
} 

当父级里程碑的estimateEnd更新时,我希望 child 的估算值自动更新相同的数量。 GORM's beforeUpdate() hook似乎很适合这样做:

为了使生活更轻松,我想使用一些 simple Date arithmetic,因此我在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 } 
        } 
    } 

没有编译错误。但是,当我运行以下集成测试时:
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 

这表明beforeUpdate没有触发并执行我想要的操作。有任何想法吗?

请您参考如下方法:

我为您提供解决方案。

1)更新里程碑1的EstimatedEnd之后,在第二个保存调用中调用save(flush:true)。这将强制beforeUpdate()立即触发。

2)即使在执行#1之后,您的断言仍将继续失败,因为您正在比较2个稍有不同的日期(您在每个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, 
        ) 

那么断言将成功。我将根据最佳方式比较稍有不同的日期留给您下一步要做什么,但是您可能必须忍受毫秒级的精度差异。

希望能有所帮助,

约旦


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!