Grails Gorm : Object references an unsaved transie

2020-04-07 04:40发布

I get the following Exception when saving an instance of Trip in Grails:

2011-01-26 22:37:42,801 [http-8090-5] ERROR errors.GrailsExceptionResolver - object references an unsaved transient instance - save the transient instance before flushing: Rower org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Rower

The concept is simple: For a boattrip you need some rowers, a coxwain (is also a rower) and a boat:

Trip looks like (shortened):

class Trip {
    Boat boat;
    Rower coxwain;

    static belongsTo = [Rower,Boat]
    static hasMany = [rowers:Rower]
}

and Rower (shortened)

class Rower { 
    String firstname;
    String name;
    Rower reference;

    static hasMany = [trips:Trip];
    static mappedBy = [trips:"rowers"]
}

The trip then is saved in the controller like:

def save = {
        def trip = new Trip(params)

        // adding Rowers to Trip
        if (params.rower instanceof String) {
            def r = Rower.get(params?.rower)

            if (r != null) {
                trip.addToRowers(r)
            }
        } else {
            params?.rower?.each{
                rowerid ->
                def r = Rower.get(rowerid)
                log.info("rowerid (asList): " + rowerid)
                if (r != null) {
                    trip.addToRowers(r)
                }
            }
        } 

        // saving the new Trip -> EXCEPTION IN NEXT LINE
        if(!trip.hasErrors() && trip.save(flush:true)) {
          // ...
        }
        // ...
}

I think I have set the relations between the domains correct. The Rower is not changed while it is added to the Trip. Why does Grails want it to save? why is it a transient instance?

标签: grails gorm
7条回答
兄弟一词,经得起流年.
2楼-- · 2020-04-07 05:07

Just a quick note for anyone dealing with singular or multiple parameters with the same name, using the params.list("parameterName") helper you can always return a list

    ...

    // adding Rowers to Trip
    if (params.rower instanceof String) {
        def r = Rower.get(params?.rower)

        if (r != null) {
            trip.addToRowers(r)
        }
    } else {
        params?.rower?.each{
            rowerid ->
            def r = Rower.get(rowerid)
            log.info("rowerid (asList): " + rowerid)
            if (r != null) {
                trip.addToRowers(r)
            }
        }
    } 

    ...

could become a bit groovier

    ...

    // adding Rowers to Trip
    for(rower in params.list("rower") {
        def r = Rower.get(rower) 
        if(r) trip.addToRowers(r)
    } 

    ...

you can find it hiding away under 6.1.12 Simple Type Converters

查看更多
登录 后发表回答