Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate Grails在更新()之前钩住GORM_Hibernate_Grails_Gorm_Grails Domain Class - Fatal编程技术网

Hibernate Grails在更新()之前钩住GORM

Hibernate Grails在更新()之前钩住GORM,hibernate,grails,gorm,grails-domain-class,Hibernate,Grails,Gorm,Grails Domain Class,我有一个嵌套域类的内部需求,我希望父关系的更新传播到子关系。代码示例可以清楚地说明: class Milestone { static belongsTo = [project:Project] static hasMany = [goals:OrgGoals, children:Milestone] String name Date start Date estimatedEnd Date achievedEnd ... } 当父里程碑

我有一个嵌套域类的内部需求,我希望父关系的更新传播到子关系。代码示例可以清楚地说明:

class Milestone {
    static belongsTo = [project:Project]
    static hasMany = [goals:OrgGoals, children:Milestone]
    String name
    Date start
    Date estimatedEnd
    Date achievedEnd
    ...
}
当父里程碑的estimatedEnd更新时,我希望子里程碑的estimatedEnd自动更新相同的数量。这样做似乎是合乎逻辑的:

为了让生活更轻松,我想使用一些,因此我在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) 更新milestone1的估计值后,在第二次调用save时调用save(刷新:true)。这将强制beforeUpdate()立即启动

2) 即使在执行#1之后,您的断言仍将继续失败,因为您正在比较两个稍有不同的日期(您在每个里程碑构造函数中使用单独的日期对象,因此第二个日期略晚于/大于第一个日期)

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,
        )
那么断言就会成功。我将把下一步要做的事情留给您,以比较稍微不同的日期的最佳方式,但您可能必须容忍毫秒级的精度差异

希望有帮助


乔丹

我有一个解决办法给你

1) 更新milestone1的估计值后,在第二次调用save时调用save(刷新:true)。这将强制beforeUpdate()立即启动

2) 即使在执行#1之后,您的断言仍将继续失败,因为您正在比较两个稍有不同的日期(您在每个里程碑构造函数中使用单独的日期对象,因此第二个日期略晚于/大于第一个日期)

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,
        )
那么断言就会成功。我将把下一步要做的事情留给您,以比较稍微不同的日期的最佳方式,但您可能必须容忍毫秒级的精度差异

希望有帮助


Jordan

为什么不使用
Estimateded
setter?我怀疑GORM事件可能在tests@Victor:说得好。我甚至没有想到这一点,但这更有意义@唐:我相信它们不会在单元测试之后执行,但它们在集成测试中会运行在一个完整的数据库上。当然。这显然是一个域逻辑,而不是一些持久性基础设施。为什么不使用
estimatedEnd
setter呢?我怀疑GORM事件可能不会在tests@Victor:说得好。我甚至没有想到这一点,但这更有意义@唐:我相信它们不会在单元测试之后执行,但它们在集成测试中会运行在一个完整的数据库上。当然。这显然是一个领域逻辑,而不是一些持久性基础设施的东西。正是这样。好节目,老伙计!我有一种刷新保存的感觉,但日期算术的事情是微妙的。谢谢你的帮助!就是这样。好节目,老伙计!我有一种刷新保存的感觉,但日期算术的事情是微妙的。谢谢你的帮助!