2011-07-13 3 views
0

基本的な問題:ProductOfferingという名前の参照エンティティを持つ多対多の関係(Stores、Products)があります。永続的なStoreLocationを持ち、一時的な製品を接続しようとする状況では、休止状態でも私はまだ保存したくないと言っています。多対多の関係を持つ複雑なフォームをレンダリングするときに、未保存の過渡エラーが発生する場合があります。

質問:

  1. なぜGrailsの/ GORM/Hibernateは私のエンティティを保存しようとしていますか?
  2. この問題にアプローチするより良い方法はありますか?

マイドメインクラスは、次のようになります。

class StoreLocation { 
    String name 
    List offerings 
    static hasMany = [offerings:ProductOffering] 
    static constraints = { 
    } 
} 

class Product { 
    String name 
    static hasMany = [offeredBy:ProductOffering] 
    static constraints = { 
     name(unique:true) 
     offeredBy(nullable:true) 
    } 
} 

class ProductOffering { 
    static belongsTo = [product:Product, store:StoreLocation] 
    static constraints = { 
    } 
} 

そして、私のStoreLocationController "編集" アクションは、次のようになります。

def edit = { 
    //get the store we want to edit 
    def storeLocation = StoreLocation.get(params.id) 
    //create a transient product and add it to the store 
    // by attaching it to a transient productOffering 
    def product = new Product() 
    def offering = new ProductOffering() 
    offering.product = product 
    storeLocation.addToOfferings(offering) 
    //render the edit page 
    render(view:"edit", model:[storeLocation:storeLocation]) 
} 

ID = 1のstoreLocationがあるとします。私はStoreLocationを編集するために行く localhost:8080/myapp/storeLocation/edit/1

私のビューがどのように見えるかは関係ありません。それは可能性があります

hello

私は次のエラーが発生します。

エラー500:nullでないプロパティがnullまたは一時的な値を参照しています:ProductOffering.product;ネストされた例外はorg.hibernate.PropertyValueExceptionです:-nullでないプロパティはnullまたは一時値を参照:ProductOffering.product

スタックトレースは、はるかに有用ではありません。

org.springframework.dao.DataIntegrityViolationException:not- nullプロパティはnull値または一時的な値を参照します

答えて

3

Grailsはすべてのリクエストの周りにOpenSessionInViewインターセプタを登録します。これにより、Hibernateセッションが各要求の期間中開かれ、要求の最後にセッションがフラッシュされ閉じられます。これには、遅延読み込みの例外を回避するという利点があります。

リクエストの最後にセッションがフラッシュされるため、ダーティな永続インスタンスがデータベースにプッシュされ、ここで発生します。 storeLocationインスタンスをロードして変更すると、変更がフラッシュされます。 storeLocationがフラッシュされたときに暫定的に保存されるため、Productインスタンスは存在しないため、この例外が発生するので、ProductOfferingを保存する必要はありません。

変更を永続化したくない場合は、変更されたインスタンスを永続コンテキストから削除します。これは、レンダリングコールの前にstoreLocation.discard()を呼び出して行います。 discardメソッドの詳細については、http://grails.org/doc/latest/ref/Domain%20Classes/discard.htmlを参照してください。

+0

完璧、ありがとうございます。永続コンテキストからStoreLocationを破棄する前に、すべての子関係を確実にロードすることが確実である限り、私はうまくいくはずです。 別の方法でアプローチできますか? grails/spring/hibernateに、セッションの終わりに暗黙的にフラッシュしないように伝えることはできますか? flush.mode = neverに設定するとどうなりますか? –

関連する問題