开发者

how to do save or update in Grails?

If the record doesnt exist, it should insert. And if the record exists, Grails should do an update.

new MyEntity(attr1:'val1', attr2:'val2').saveOrUpdate()????

EDIT I have modified my code as per your suggestions:

List<NutDto> res = np.parseNutData(file.inputStream);
for(NutDto cellValue : res){
    def nutInstance = NutData.get(cellValue.getIdd())       
    System.out.println("nutInstance = " + nutInstance);         
    if(nutInstance){
        System.out.println("Exists : " + nutInstance);
        nutInstance.foo=cellValue.getFoo()
        nutInstance.bar=cellValue.getBar()              
    }
    else{
        System.out.println("Not Exists")
        nutInstance =   new NutData(idd:cellValue.getIdd(),
                foo:cellValue.getFoo(),
                bar:cellValue.getBar())
    }

    def saveres = nutInstance.save(failOnError: true);
    println("saveres = " + saveres);
    nutInstance.errors.each { println it }
}

Still its not updating. Its throwing errors.

Field error in object 'sps.NutData' on field 'idd': rejected value [123456-1234]; codes [sps.NutData.idd.unique.error.sps.NutData.idd,sps.NutData.idd.unique.error.idd,sps.NutData.idd.unique.error.java.lang.String,sps.NutData.idd.unique.error,nutData.idd.unique.error.sps.NutData.idd,nutData.idd.unique.error.idd,nutData.idd.unique.error.java.lang.String,nutData.idd.unique.error,sps.NutData.idd.unique.sps.NutData.idd,sps.NutData.idd.unique.idd,sps.NutData.idd.unique.java.lang.String,sps.NutData.idd.unique,nutData.idd.unique.sps.NutData.idd,nutData.idd.unique.idd,nutData.idd.unique.java.lang.String,nutData.idd.unique,unique.sps.NutData.idd,unique.idd,unique.java.lang.String,unique]; arguments [idd,class sps.NutData,123456-1234]; default message [Property [{0}] of class [{1}] with value [{2}] must be unique]

The values are not getting updated.

开发者_运维知识库EDIT 2

package sps    
class NutData {

    String idd
    String foo
    String bar


    static constraints = {
        idd(blank:false, unique:true)
    }

    static mapping = {
        table 'M_NUT_DATA'
        version false
        id generator: 'assigned', name: "idd", type: 'string'
        foo column:'FOO_COL'
        bar column:'BAR_COL'        
    }

    String toString(){
        return idd + '_' + foo
    }
}


Dynamic finders are precisely available for this purpose.

Using findOrSaveBy* your first sample code would be written as such:

def entity = MyEntity.findOrSaveByAttr1AndAttr2( val1, val2 )

Documentation : http://grails.org/doc/latest/ref/Domain%20Classes/findOrSaveBy.html


A .save() should do this all, but it depends on the way you created the object.

if you use new MyEntity(..) grails will create the record, if you get the object from database, the save will do an update.


You could use the following code (replace Widget with your class/entity):

def widgetInstance = Widget.findByName('firstWidget') ?: new Widget(name: 'firstWidget').save(failOnError: true)

The argument to the save functions "failOnError: true" will ensure that the code will fail in case there is an error.


Like elCapitano says, the problem here depends a lot on the way you obtain the object.

If you get the object from database, then modify it, you just need to call save() on the object.

If you create a new object (like your example): now it depends on how you know "the same object already exists in database". You must perform query to determine if the object already exists, then perform update or create accordingly. There's no shortcut for that.

But more often, the problem isn't that complicated, since usually you only update object if already loading it (to a form, for example) for users to edit. Otherwise, you know you need to create the object.

You can use grails scaffolding function to see the typical model how Grails do CRUD(create-update-delete).


In order to update the record we should be clear with -- If my domain class has a,b,c and d fields. Then, while trying to save if a and b are same than update the record other wise insert a new record.

So, First of all identify these fields in your domain class.

Then we need a saveOrUpdate method on the domain class which does something like following:

//This method is present in domain class
saveOrUpdate()
{
   //listOfFields is a list of fields that are identifiers or the once that decide whether to update or insert.
   def existingObject = DomainClass.findWhere([this.properties.subMap(listOfFields)])

   if(existingObject)
   {
      // Hey!!! This object already exists in DB. Let us update it .... 
      // Update the existingObject and save the same
   }
else{
    // No object already exists in the DB so, let us create a new one and save it.
   } 
}

In case you would like to go through a working implementation of the same please refer to my blog :

http://www.intelligrape.com/blog/2011/03/15/implementing-saveorupdate-for-domain-classes/

Hope this helps.


a '.save()' should do this all, but it depends on the way you created the object.

if you use 'new MyEntitiy(..)' grails will create the record, if you get the object from >> database, the save will do an update.

Exactly to the point. First retrieve the object, check what's changed then save it back. Using new would create another entry in the DB during the save "just because" it's a new object.

def gottenFromDB = TheObject.get( params.id ) ; //for example
def updatesObject = new MakeNewObjectFromJSON( request ) ; // this one contains the updates

// either check property  by property or just update all properties 
// whatever is more efficiente or if you don't care.

gottenFromDB.prop1 = updatesObject.prop1
gottenFromDB.prop2 = updatesObject.prop2
gottenFromDB.propN   = updatesObject.propN

gottenFromDB.save() ; // this will perform "update"


findOrSaveBy... does not update existing data. Hence, I wrote my own code for a domain called Person.

Boolean saveOrUpdate(Integer id, String name, Status status, Date startDate) {

    Person person = Person.findById(id)

    //If the person is new, create a new instance and assign ID
    if(!person) {
        person = new Person()
        person.setId(id.toLong()) 
       /** I set the ID here because I am using Postgres and I want to assign the ID manually
       `static mapping = {
           id generator: 'assigned'
        }`
       */
    }

    person.name = name
    person.status = status
    person.startDate = startDate
    person.save(flush: true, failOnError: true)

    if (person?.hasErrors()) {
        log.error("Person ${id} is not saved. Domain Errors: ${person?.errors}")
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜