Question

I'd like to be able to update a previously persisted object for which I have an id without having to retrieve it first. The main thing that I'm trying to avoid is having to copy multiple values into the object's fields when that object has been retrieved from the database. I have these values in a map with keys corresponding to the field names so it's trivial to create the object via a constructor with the map as an argument. Unfortunately, an object created this way results in a new database record when saved even though the id field is set to that of an existing record.

I'm currently using a slight variation on one of the examples shown here for copying Groovy class properties but it's not a very elegant solution for multiple reasons.

Basically I'd like to be able to do something like this:

class Foo {
    int a
    String b
}

def data = [id: 99, a: 11, b: "bar"]    //99 is the id of an existing record
def foo = new Foo(data)
foo.update()    //or some other comparable persistence mechanism

Thanks

Était-ce utile?

La solution

As long as your map keys have the same name as your object properties, you can use executeUpdate without specifying the individual property names with a closure or function like the following:

def updateString = { obj, map ->
        def str = ""
        map.each { key, value ->
            str += "${obj}.${key}=:${key},"
        }

        return str[0..-2]
    }

    def data= [foo:"bar", machoMan:"RandySavage"]

In this case, println updateString("f", data) returns "f.foo=:foo,f.machoMan=:machoMan".

Then you can do this:

Foo.executeUpdate("update Foo f set ${updateString("f", data)}", data)

Or of course you could combine that all together into one closure or function.

Autres conseils

You can use the executeUpdate method on the GORM domain class:

Foo.executeUpdate("update Foo f set f.a=:a, f.b=:b where f.id=:id", data)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top