Note that there are some explanatory texts on larger screens.

plurals
  1. POGrails hook into GORM beforeUpdate()
    primarykey
    data
    text
    <p>I have an internal requirement with nested domain classes where I want updates to a parent relationship to be propagated to children. A code example may make it clear:</p> <pre><code>class Milestone { static belongsTo = [project:Project] static hasMany = [goals:OrgGoals, children:Milestone] String name Date start Date estimatedEnd Date achievedEnd ... } </code></pre> <p>When the parent milestone's estimatedEnd is updated, I want the children's estimated to automatically be updated by the same amount. <a href="http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20%28GORM%29.html#5.5.1%20Events%20and%20Auto%20Timestamping%20vvv" rel="nofollow">GORM's beforeUpdate() hook</a> seems like a logical place to do this:</p> <p>To make life easier, I'd like to use some <a href="http://groovy.codehaus.org/JN0545-Dates" rel="nofollow">simple Date arithmetic</a>, so I've added the following method to the Milestone class:</p> <pre><code>def beforeUpdate() { // check if an actual change has been made and the estimated end has been changed if(this.isDirty() &amp;&amp; this.getDirtyPropertyNames().contains("estimatedEnd")) { updateChildEstimates(this.estimatedEnd,this.getPersistentValue("estimatedEnd")) } } private void updateChildEstimates(Date newEstimate, Date original) { def difference = newEstimate - original if(difference &gt; 0) { children.each{ it.estimatedEnd+= difference } } } </code></pre> <p>No compilation errors. But when I run the following integration test:</p> <pre><code>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) } </code></pre> <p>I get:</p> <pre><code>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 </code></pre> <p>Which suggests that the beforeUpdate is not firing and doing what I want. Any ideas?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload