when to save? hibernate dirty updates 1.0RC1

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

when to save? hibernate dirty updates 1.0RC1

Garrotin
Hello all,  I believe I have fell victim to the dirty updates automatically done by hibernate.  I have a situation in the update closure of the grails controller is saving when validation fails.  So I have been able to work around this using the discard() method.  Attach is my Controller.  My problem lies with validating multiple associated objects, such as Address, SosStaff etc.  So my question.  Is there a better way to handle my validation to avoid the use of discard()?  Maybe this is where Command Objects would come into play.  I am confused how to use these though.  Anyway here is the update method of the controller.  The complete file is attached.   The validateOtherPrograms, validateNumberServed methods are custom validation based on some business rules these might be the candidates for Command Objects.  If I understand them correctly.  The creation of the newGrantee is my temporary work around and is used to send back to the edit view to display error messages since I have to do a sosGrantee.discard() to keep it from saving.  There has to be a  cleaner or groovier was to do this.  Any help would be greatly appreciated.

//Reference to similiar bug  GRAILS-1622

    def update = {
        def sosGrantee = SosGrantee.get( params.id )
        def newGrantee = SosGrantee.get( params.id )
        if(sosGrantee) {
            sosGrantee.properties = params
            newGrantee.properties = params
            sosGrantee.setModifiedById(auth.principal?.domainClass.id.intValue())
            sosGrantee.setModifiedTs(new Date())
            if(!validateOtherPrograms(sosGrantee) &&
               !validateNumberServed(sosGrantee)&&
               !sosGrantee.hasErrors()&&
                sosGrantee.save()) {
                flash.message = "SosGrantee ${params.id} updated"
                redirect(action:show,id:sosGrantee.id)
            }
            else {
            sosGrantee.discard()
                render(view:'edit',model:['sosGrantee':newGrantee])
            }
        }
        else {
            flash.message = "SosGrantee not found with id ${params.id}"
            redirect(action:edit,id:params.id)
        }
    }

Program.groovy
<BR>
SosGrantee.groovy<BR>
SosGranteeController.groovy
Reply | Threaded
Open this post in threaded view
|

Re: when to save? hibernate dirty updates 1.0RC1

burtbeckwith
I don't have much help for this issue but I noticed a couple of things about
your code. You call SosGrantee.get( params.id ) twice, but you're get the
same instance each time, not two different instances with the same data. This
is a feature of Hibernate's 1st-level cache - multiple calls within the same
Session hit the database just once. To see that this is the case, add the
line

   println sosGrantee.is(newGrantee)

or even

   assert sosGrantee.is(newGrantee)

and you'll see that they're the same object.

Also, you don't need to explicitly set the last-modified date, you can define
a "lastUpdated" Date field in your model class and Grails will automatically
update it each time the object is updated. Since you're also recording the id
of the updating user, you could use a beforeUpdate event to set the
modifiedById - see http://docs.codehaus.org/display/GRAILS/GORM+-+Events

Burt

On Tuesday 26 February 2008 8:21:09 pm Garrotin wrote:

> Hello all,  I believe I have fell victim to the dirty updates automatically
> done by hibernate.  I have a situation in the update closure of the grails
> controller is saving when validation fails.  So I have been able to work
> around this using the discard() method.  Attach is my Controller.  My
> problem lies with validating multiple associated objects, such as Address,
> SosStaff etc.  So my question.  Is there a better way to handle my
> validation to avoid the use of discard()?  Maybe this is where Command
> Objects would come into play.  I am confused how to use these though.
> Anyway here is the update method of the controller.  The complete file is
> attached.   The validateOtherPrograms, validateNumberServed methods are
> custom validation based on some business rules these might be the
> candidates for Command Objects.  If I understand them correctly.  The
> creation of the newGrantee is my temporary work around and is used to send
> back to the edit view to display error messages since I have to do a
> sosGrantee.discard() to keep it from saving.  There has to be a  cleaner or
> groovier was to do this. Any help would be greatly appreciated.
>
> //Reference to similiar bug  GRAILS-1622
>
>     def update = {
>         def sosGrantee = SosGrantee.get( params.id )
>         def newGrantee = SosGrantee.get( params.id )
>         if(sosGrantee) {
>             sosGrantee.properties = params
>             newGrantee.properties = params
>
> sosGrantee.setModifiedById(auth.principal?.domainClass.id.intValue())
>             sosGrantee.setModifiedTs(new Date())
>             if(!validateOtherPrograms(sosGrantee) &&
>                !validateNumberServed(sosGrantee)&&
>                !sosGrantee.hasErrors()&&
>                 sosGrantee.save()) {
>                 flash.message = "SosGrantee ${params.id} updated"
>                 redirect(action:show,id:sosGrantee.id)
>             }
>             else {
>             sosGrantee.discard()
>                 render(view:'edit',model:['sosGrantee':newGrantee])
>             }
>         }
>         else {
>             flash.message = "SosGrantee not found with id ${params.id}"
>             redirect(action:edit,id:params.id)
>         }
>     }
>
> http://www.nabble.com/file/p15703975/Program.groovy Program.groovy
> <BR>
> http://www.nabble.com/file/p15703975/SosGrantee.groovy SosGrantee.groovy
> <BR>
> http://www.nabble.com/file/p15703975/SosGranteeController.groovy
> SosGranteeController.groovy



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: when to save? hibernate dirty updates 1.0RC1

Garrotin
Burt,

Thanks for the info.  I was not aware of the dup objects created from the same session.  I wish I did not have to do this to get around auto update feature of hibernate.  But the newSosGrantee is the object I send back to the view when there are validation errors.  Thanks for the idea on the last lastUpdated.  I knew there was probably something I could use to do that.  Can you map it to any column I suppose?  We use modifiedTS, modifedById, createdTs and createdById.  I am extending a SecueSosBaseController which has a beforeInterceptor in it the pulls the auth object and checks for use session.  Again thanks, Hopefully I will figure out a cleaner way to handle the dirty save issue.


burtbeckwith wrote
I don't have much help for this issue but I noticed a couple of things about
your code. You call SosGrantee.get( params.id ) twice, but you're get the
same instance each time, not two different instances with the same data. This
is a feature of Hibernate's 1st-level cache - multiple calls within the same
Session hit the database just once. To see that this is the case, add the
line

   println sosGrantee.is(newGrantee)

or even

   assert sosGrantee.is(newGrantee)

and you'll see that they're the same object.

Also, you don't need to explicitly set the last-modified date, you can define
a "lastUpdated" Date field in your model class and Grails will automatically
update it each time the object is updated. Since you're also recording the id
of the updating user, you could use a beforeUpdate event to set the
modifiedById - see http://docs.codehaus.org/display/GRAILS/GORM+-+Events

Burt

On Tuesday 26 February 2008 8:21:09 pm Garrotin wrote:
> Hello all,  I believe I have fell victim to the dirty updates automatically
> done by hibernate.  I have a situation in the update closure of the grails
> controller is saving when validation fails.  So I have been able to work
> around this using the discard() method.  Attach is my Controller.  My
> problem lies with validating multiple associated objects, such as Address,
> SosStaff etc.  So my question.  Is there a better way to handle my
> validation to avoid the use of discard()?  Maybe this is where Command
> Objects would come into play.  I am confused how to use these though.
> Anyway here is the update method of the controller.  The complete file is
> attached.   The validateOtherPrograms, validateNumberServed methods are
> custom validation based on some business rules these might be the
> candidates for Command Objects.  If I understand them correctly.  The
> creation of the newGrantee is my temporary work around and is used to send
> back to the edit view to display error messages since I have to do a
> sosGrantee.discard() to keep it from saving.  There has to be a  cleaner or
> groovier was to do this. Any help would be greatly appreciated.
>
> //Reference to similiar bug  GRAILS-1622
>
>     def update = {
>         def sosGrantee = SosGrantee.get( params.id )
>         def newGrantee = SosGrantee.get( params.id )
>         if(sosGrantee) {
>             sosGrantee.properties = params
>             newGrantee.properties = params
>
> sosGrantee.setModifiedById(auth.principal?.domainClass.id.intValue())
>             sosGrantee.setModifiedTs(new Date())
>             if(!validateOtherPrograms(sosGrantee) &&
>                !validateNumberServed(sosGrantee)&&
>                !sosGrantee.hasErrors()&&
>                 sosGrantee.save()) {
>                 flash.message = "SosGrantee ${params.id} updated"
>                 redirect(action:show,id:sosGrantee.id)
>             }
>             else {
>             sosGrantee.discard()
>                 render(view:'edit',model:['sosGrantee':newGrantee])
>             }
>         }
>         else {
>             flash.message = "SosGrantee not found with id ${params.id}"
>             redirect(action:edit,id:params.id)
>         }
>     }
>
> http://www.nabble.com/file/p15703975/Program.groovy Program.groovy
> <BR>
> http://www.nabble.com/file/p15703975/SosGrantee.groovy SosGrantee.groovy
> <BR>
> http://www.nabble.com/file/p15703975/SosGranteeController.groovy
> SosGranteeController.groovy



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: when to save? hibernate dirty updates 1.0RC1

justinedelson
It looks like if you could have the validateOtherPrograms() and validateNumberServed() validations be part of the domain class's constraints, you wouldn't have this problem (and your code would be cleaner). See http://grails.org/doc/1.0.x/ref/Constraints/validator.html for details on writing a custom validator.


On Wed, Feb 27, 2008 at 8:36 AM, Garrotin <[hidden email]> wrote:

Burt,

Thanks for the info.  I was not aware of the dup objects created from the
same session.  I wish I did not have to do this to get around auto update
feature of hibernate.  But the newSosGrantee is the object I send back to
the view when there are validation errors.  Thanks for the idea on the last
lastUpdated.  I knew there was probably something I could use to do that.
Can you map it to any column I suppose?  We use modifiedTS, modifedById,
createdTs and createdById.  I am extending a SecueSosBaseController which
has a beforeInterceptor in it the pulls the auth object and checks for use
session.  Again thanks, Hopefully I will figure out a cleaner way to handle
the dirty save issue.



burtbeckwith wrote:
>
> I don't have much help for this issue but I noticed a couple of things
> about
> your code. You call SosGrantee.get( params.id ) twice, but you're get the
> same instance each time, not two different instances with the same data.
> This
> is a feature of Hibernate's 1st-level cache - multiple calls within the
> same
> Session hit the database just once. To see that this is the case, add the
> line
>
>    println sosGrantee.is(newGrantee)
>
> or even
>
>    assert sosGrantee.is(newGrantee)
>
> and you'll see that they're the same object.
>
> Also, you don't need to explicitly set the last-modified date, you can
> define
> a "lastUpdated" Date field in your model class and Grails will
> automatically
> update it each time the object is updated. Since you're also recording the
> id
> of the updating user, you could use a beforeUpdate event to set the
> modifiedById - see http://docs.codehaus.org/display/GRAILS/GORM+-+Events
>
> Burt
>
> On Tuesday 26 February 2008 8:21:09 pm Garrotin wrote:
>> Hello all,  I believe I have fell victim to the dirty updates
>> automatically
>> done by hibernate.  I have a situation in the update closure of the
>> grails
>> controller is saving when validation fails.  So I have been able to work
>> around this using the discard() method.  Attach is my Controller.  My
>> problem lies with validating multiple associated objects, such as
>> Address,
>> SosStaff etc.  So my question.  Is there a better way to handle my
>> validation to avoid the use of discard()?  Maybe this is where Command
>> Objects would come into play.  I am confused how to use these though.
>> Anyway here is the update method of the controller.  The complete file is
>> attached.    The validateOtherPrograms, validateNumberServed methods are
>> custom validation based on some business rules these might be the
>> candidates for Command Objects.  If I understand them correctly.  The
>> creation of the newGrantee is my temporary work around and is used to
>> send
>> back to the edit view to display error messages since I have to do a
>> sosGrantee.discard() to keep it from saving.  There has to be a  cleaner
>> or
>> groovier was to do this. Any help would be greatly appreciated.
>>
>> //Reference to similiar bug  GRAILS-1622
>>
>>     def update = {
>>         def sosGrantee = SosGrantee.get( params.id )
>>         def newGrantee = SosGrantee.get( params.id )
>>         if(sosGrantee) {
>>             sosGrantee.properties = params
>>             newGrantee.properties = params
>>
>> sosGrantee.setModifiedById(auth.principal?.domainClass.id.intValue())
>>             sosGrantee.setModifiedTs(new Date())
>>             if(!validateOtherPrograms(sosGrantee) &&
>>                !validateNumberServed(sosGrantee)&&
>>                !sosGrantee.hasErrors()&&
>>                 sosGrantee.save()) {
>>                 flash.message = "SosGrantee ${params.id} updated"
>>                 redirect(action:show,id:sosGrantee.id)
>>             }
>>             else {
>>              sosGrantee.discard()
>>                 render(view:'edit',model:['sosGrantee':newGrantee])
>>             }
>>         }
>>         else {
>>             flash.message = "SosGrantee not found with id ${params.id}"
>>             redirect(action:edit,id:params.id)
>>         }
>>     }
>>
>> http://www.nabble.com/file/p15703975/Program.groovy Program.groovy
>> <BR>
>> http://www.nabble.com/file/p15703975/SosGrantee.groovy SosGrantee.groovy
>> <BR>
>> http://www.nabble.com/file/p15703975/SosGranteeController.groovy
>> SosGranteeController.groovy
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>
>

--
View this message in context: http://www.nabble.com/when-to-save--hibernate-dirty-updates-1.0RC1-tp15703975p15713268.html
Sent from the grails - user mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: when to save? hibernate dirty updates 1.0RC1

burtbeckwith
In reply to this post by Garrotin
You can add a static 'mapping' closure to your domain class to override the
column name for lastUpdated, e.g.

class Thing {

   String foo
   Date lastUpdated

   static mapping = {
      columns {
         lastUpdated column: 'modifiedTS'
      }
   }
}

Burt

On Wednesday 27 February 2008 8:36:58 am Garrotin wrote:

> Burt,
>
> Thanks for the info.  I was not aware of the dup objects created from the
> same session.  I wish I did not have to do this to get around auto update
> feature of hibernate.  But the newSosGrantee is the object I send back to
> the view when there are validation errors.  Thanks for the idea on the last
> lastUpdated.  I knew there was probably something I could use to do that.
> Can you map it to any column I suppose?  We use modifiedTS, modifedById,
> createdTs and createdById.  I am extending a SecueSosBaseController which
> has a beforeInterceptor in it the pulls the auth object and checks for use
> session.  Again thanks, Hopefully I will figure out a cleaner way to handle
> the dirty save issue.
>
> burtbeckwith wrote:
> > I don't have much help for this issue but I noticed a couple of things
> > about
> > your code. You call SosGrantee.get( params.id ) twice, but you're get the
> > same instance each time, not two different instances with the same data.
> > This
> > is a feature of Hibernate's 1st-level cache - multiple calls within the
> > same
> > Session hit the database just once. To see that this is the case, add the
> > line
> >
> >    println sosGrantee.is(newGrantee)
> >
> > or even
> >
> >    assert sosGrantee.is(newGrantee)
> >
> > and you'll see that they're the same object.
> >
> > Also, you don't need to explicitly set the last-modified date, you can
> > define
> > a "lastUpdated" Date field in your model class and Grails will
> > automatically
> > update it each time the object is updated. Since you're also recording
> > the id
> > of the updating user, you could use a beforeUpdate event to set the
> > modifiedById - see http://docs.codehaus.org/display/GRAILS/GORM+-+Events
> >
> > Burt
> >
> > On Tuesday 26 February 2008 8:21:09 pm Garrotin wrote:
> >> Hello all,  I believe I have fell victim to the dirty updates
> >> automatically
> >> done by hibernate.  I have a situation in the update closure of the
> >> grails
> >> controller is saving when validation fails.  So I have been able to work
> >> around this using the discard() method.  Attach is my Controller.  My
> >> problem lies with validating multiple associated objects, such as
> >> Address,
> >> SosStaff etc.  So my question.  Is there a better way to handle my
> >> validation to avoid the use of discard()?  Maybe this is where Command
> >> Objects would come into play.  I am confused how to use these though.
> >> Anyway here is the update method of the controller.  The complete file
> >> is attached.   The validateOtherPrograms, validateNumberServed methods
> >> are custom validation based on some business rules these might be the
> >> candidates for Command Objects.  If I understand them correctly.  The
> >> creation of the newGrantee is my temporary work around and is used to
> >> send
> >> back to the edit view to display error messages since I have to do a
> >> sosGrantee.discard() to keep it from saving.  There has to be a  cleaner
> >> or
> >> groovier was to do this. Any help would be greatly appreciated.
> >>
> >> //Reference to similiar bug  GRAILS-1622
> >>
> >>     def update = {
> >>         def sosGrantee = SosGrantee.get( params.id )
> >>         def newGrantee = SosGrantee.get( params.id )
> >>         if(sosGrantee) {
> >>             sosGrantee.properties = params
> >>             newGrantee.properties = params
> >>
> >> sosGrantee.setModifiedById(auth.principal?.domainClass.id.intValue())
> >>             sosGrantee.setModifiedTs(new Date())
> >>             if(!validateOtherPrograms(sosGrantee) &&
> >>                !validateNumberServed(sosGrantee)&&
> >>                !sosGrantee.hasErrors()&&
> >>                 sosGrantee.save()) {
> >>                 flash.message = "SosGrantee ${params.id} updated"
> >>                 redirect(action:show,id:sosGrantee.id)
> >>             }
> >>             else {
> >>             sosGrantee.discard()
> >>                 render(view:'edit',model:['sosGrantee':newGrantee])
> >>             }
> >>         }
> >>         else {
> >>             flash.message = "SosGrantee not found with id ${params.id}"
> >>             redirect(action:edit,id:params.id)
> >>         }
> >>     }
> >>
> >> http://www.nabble.com/file/p15703975/Program.groovy Program.groovy
> >> <BR>
> >> http://www.nabble.com/file/p15703975/SosGrantee.groovy SosGrantee.groovy
> >> <BR>
> >> http://www.nabble.com/file/p15703975/SosGranteeController.groovy
> >> SosGranteeController.groovy
> >
> > ---------------------------------------------------------------------
> > To unsubscribe from this list, please visit:
> >
> >     http://xircles.codehaus.org/manage_email



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email