2010-02-23 4 views
1

간단한 그루비 \ Grails의 코드 :Grails의 : org.hibernate.TransientObjectException

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는이 ("시작"방법 \ 폐쇄 실행이 끝난 후 프로그램 인쇄 "끝"예외가 발생합니다, "OK"메시지를 렌더링 한 후 발생 예외) :

org.springframework.dao.InvalidDataAccessApiUsageException : - : com.stanfy.sweethome.domains.Hotel을 객체가 저장되지 않은 과도 인스턴스를 참조는 세척하기 전에 transient 인스턴스를 저장 ; 상자의 예외는

org.hibernate.TransientObjectException입니다 : 객체가 저장되지 않은 transient 인스턴스 참조 - 세척하기 전에 transient 인스턴스를 저장합니다 com.stanfy.sweethome.domains.Hotel 을 java.lang.Thread.run에서을 (org.hibernate.TransientObjectException : Thread.java:619)

에 의한 개체가 저장되지 않은 과도 인스턴스를 참조 - 세척하기 전에 transient 인스턴스를 저장합니다 com.stanfy.sweethome.domains.Hotel ... 1 더

답변

3

컬렉션 매핑에서 cascade=CascadeType.ALL을 지정해야합니다 (정확히 어떻게 그루비가 될지 모르겠습니다).

예외는 요소가 유지되지 않는 컬렉션이 있음을 의미합니다. Hibernate는 위의 옵션이 설정되어있을 때만 자동적으로 그것을 유지한다.

P. 이 예외에 관해서는 수백 개의 스레드가 있습니다 (SO에서도 마찬가지입니다).

1

Hotel 개체에 HotelPhotosHotelFeatures의 콜렉션이 있습니까? 그렇다면 과 같이 hotel.addToHotelPhotos(...)hotel.addToHotelFeatures(...)을 사용하여 각각을 추가해야합니다.

그런 다음 호텔에서 한 번만 저장을 호출하면 모든 다른 인스턴스가 저장됩니다 (기본 동작은 계단식으로 연결됨).