Gambo
Gambo

Reputation: 1572

Grails Gorm Partial Save

I have a very basic question in saving objects which I get from a client sent via JSON.

I have a customer object which is transfered to the client, after editing the customer its send back to Grails and needs to be saved in the database. For performance I am not sending the complete customer object over the wire.

The problem is now if I want to store the customer object Grails validates of course the relationships of the customer object and fails. This is OK because I havent sent the relationsships.

My question is now how do I solve this problem now? Do I need to query the database again with the customer id and update the edited properties or is there a more elegant way? This looks a little bit expensive from database perspective as I need to read the database each time when storeing an object. As well from code perspective I need to check which properties are set and update them.

Thank you!

Upvotes: 2

Views: 1312

Answers (1)

Chris
Chris

Reputation: 8109

You cannot use save() for doing partial update, since grails cannot guess what fields you actually want to update: Maybe you REALLY want to set a field-value to NULL, so Grails cannot just ignore those fields. So I see two options:

  1. Do it like you have described: Load the instance from DB, set the values and save again. You have mentioned, that you do not like to care what fields are updated, and you just want to take all attributes of your JSON instance. So assuming your already parsed JSON-instance is called jsonInstance and your database version of the customer is customerInstance, you can do:

     jsonInstance.properties.each { field -> 
         customerInstance."${field.key}" = field.value
     }
    

    However, note that there are security limitations (if an attacker injects an 'id' attribute or other relevant attribute values into it, those will be just overwritten).

  2. Use executeUpdate-function, see: http://www.grails.org/doc/latest/ref/Domain%20Classes/executeUpdate.html

    I think, if you really want to save performance, then go like this. However you have some hardcoded DML, which will cost maintainability and flexibility.

Upvotes: 3

Related Questions