Grails:org.hibernate.TransientObjectException

时间:2010-02-23 08:36:11

标签: hibernate grails groovy

简单的Groovy \ Grails代码:

def start = {
        source.save()

        def result = getJson(hotelSite, eng + index, [:])
        parse(JSONObject.fromObject( result.json.text() ))

        render "OK" 
    }

    def parse = {JSONObject json ->
        def cities = json.get("filter").cities
        println cities
        def kievHotels = getJson(hotelSite, eng + root + '/searchhotelsbycity', ['city' : 'kiev'])
        kievHotels = JSONObject.fromObject(kievHotels.json.text())
        println kievHotels

        kievHotels.rows.each { ht->
            HotelText hotelText = new HotelText(lang : 'en', name : ht.l_name, description : ht.description, address : ht.address)
            hotelText.save(/*flush:true*/)
            println "hotel text saved"
            Hotel hotel = new Hotel(lat : ht.lat, lon : ht.lon, source : source, sourceid : ht.id)
            hotel.addToHotelTexts(hotelText)
            //hotel.save(/*flush:true*/)
            println "hotel saved"
            ht.options.each {op->
              new HotelFeatures(lang:'en', name : op, source : source, hotel : hotel).save()
            }
            println "options saved"
            ht.photos.each {ph->
                new HotelPhotos(hotel : hotel, photourl : ph, type : 'hotel').save()
            }
            println "photo saved"
            hotel.save()
        }
        println "THE END"
        return "THE END"
    }

    def getJson = {uri, path, query ->
        Thread.sleep(10)
        return withHttp(uri: uri) {
            return get(path : path, query : query) { resp, json ->

                return ['response' : resp, 'json' : json ]

            }
        }
    }

所有必须完美但grails在“start”方法结束后抛出异常\闭包执行(程序打印“THE END”,呈现“OK”消息然后抛出异常):

org.springframework.dao.InvalidDataAccessApiUsageException :对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例: com.stanfy.sweethome.domains.Hotel ;嵌套异常是

org.hibernate.TransientObjectException :对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例: com.stanfy.sweethome.domains.Hotel     在java.lang.Thread.run(Thread.java:619)

引起: org.hibernate.TransientObjectException :对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例: com.stanfy.sweethome.domains.Hotel     ......还有1个

2 个答案:

答案 0 :(得分:3)

在你的集合映射中,你必须指定cascade=CascadeType.ALL(我不知道它在groovy中究竟是多少)。

该异常意味着您有一个其元素未被持久化的集合。只有在设置了上述选项后,Hibernate才会自动保留它们。

P.S。有关此异常的数百个线程(在SO上也是如此),您可以搜索。

答案 1 :(得分:1)

您的HotelPhotos对象上是否有HotelFeaturesHotel的集合?如果是这样,您需要使用hotel.addToHotelPhotos(...)hotel.addToHotelFeatures(...)添加每个内容,就像使用HotelTexts一样。

然后你应该只需要在酒店调用一次保存,并保存所有其他实例(因为默认行为是级联)。