Simple Groovy\Grails code:
def start = {
source.save()
def result = getJson(hotelSite, eng + index, [:])
parse(JSONObject.fromObj开发者_开发知识库ect( 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 ]
}
}
}
All must be perfect but grails throws exception after the end of "start" method\closure execution(program prints "THE END", renders "OK" message and then throws exception):
org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: com.stanfy.sweethome.domains.Hotel; nested exception is
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.stanfy.sweethome.domains.Hotel at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.stanfy.sweethome.domains.Hotel ... 1 more
In your collection mapping you have to specify cascade=CascadeType.ALL
(I don't know how exactly it will be in groovy).
The exception means that you have a collection whose elements are not persisted. Hibernate persists them automatically only if the above option is set.
P.S. There are hundreds of threads (on SO as well) about this exception, you could've searched.
Do you have collections of HotelPhotos
and HotelFeatures
on your Hotel
object? If so you will need to add each of them using hotel.addToHotelPhotos(...)
and hotel.addToHotelFeatures(...)
, like you have with HotelTexts
.
Then you should only need to call save on the hotel once and all the other instances will be saved (as the default behaviour is to cascade).
精彩评论