2009-04-29 15 views
1

オブジェクトProductSupplierの間には多対1の関係があります。私はそれに属するProductを削除せずにSupplierを削除する必要があります。ここで親を削除するNHibernateの多対1リレーションシップ

は、クラスの簡易版である:

public class Supplier { 
    public virtual IList<Product> Products { get; protected set; } 
} 

public class Product { 
    // Product belongs to a Category but Supplier is optional 
    public virtual Supplier Supplier { get; set; } 
    public virtual Category Category { get; set; } 
} 

私はFluentNHibernateを使用していますが、ここではそれが生成するマッピングです:

<bag name="Products" cascade="save-update" inverse="true"> 
     <key column="SupplierID" /> 
     <one-to-many class="Me.Product, Me, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
</bag> 

<many-to-one name="Supplier" column="SupplierID" /> 

これは、Productsテーブルの外部キーを作成し、私がサプライヤでストレート削除をしようとすると、私は外部キー制約エラーを取得します。私はカスケードを「すべて」に変更しようとしましたが、関係を削除するだけで、すべてのプロダクトと他の関連オブジェクトが削除されることを願っていました。

この問題を解決するには、サプライヤのProductsコレクションを繰り返し、サプライヤプロパティをnullに設定するしかありません。マッピングを通じてこの動作を達成できる方法はありますか?

+0

DBは自動的に生成されます。 – roryf

+0

さらに、ファントムサプライヤIDの値には関係がありません – roryf

答えて

2

マッピングプロパティは、エンティティが実際にロードされたとき、およびHQLでクエリを実行していないときにのみ有効です。たとえば、Cascade=ALLと指定した場合、クエリ"delete from Supplier where id=:id"を持つサプライヤを削除すると、hqlが(プログラム的な)カスケードをトリガしないため、おそらく同じFK制約が失敗します。

商品は関係の所有側であると思われます。

  • コードのすべての製品を反復処理し、nullに製品のサプライヤーを設定、および削除サプライヤーを発行する前にすべてのサプライヤー
  • を削除する前に、このメソッドを使用し、作るためにサプライヤーにいくつかの方法:私は、次の2つの選択肢があると思います必ずあなたのDAOは、製品の供給者が

例をnullに設定します。

public int Delete(Supplier s) { 
    return Session.CreateQuery("udpate Product set Supplier = null where Supplier = :supplier") 
     .SetParameter("supplier", s) 
     .ExecuteUpdate(); 
} 
+0

データアクセス層内のクエリとしてこれを行うとは考えていませんでしたが、これは完璧でした! – roryf

+0

HQLでUPDATEまたはDELETEステートメントを実行できないことがわかります。これを行うための方法は、未処理のSQLだけです。この場合、私はそれで生きることができます。 – roryf

+0

本当ですか?私はコード全体を削除しています: svc。getEm()。createQuery( "UserOperatorEJBからの削除").executeUpdate(); このリンクもチェックしてください: http://www.java2s.com/Code/Java/Hibernate/HQLDeleteHQL.htm http://twasink.net/blog/2005/04/differences-in-behaviour-between- hibernate-delete-query-and-the-way/ hibernateドキュメントサイトがダウンしていると、ひどいです。 –

0

これを行いません。

モデルには、すべての製品にサプライヤがあるという暗黙的または明示的なアサーションがあります。外部キーは、この条件を強制するためのものです。プロダクトを保持している間にサプライヤを削除するとモデルに違反し、これが常に真実であることに依存するコードの多くが失敗する可能性があります。

あなたができることの1つは、あなたが既に発見したことです。このサプライヤを持つすべての製品について、サプライヤのnullを設定できます。これはあなたの状態に違反しませんが、「この製品のサプライヤが誰であるかわからず、コードが失敗する可能性があります」と同じです。

なぜこれをやりたいですか?

+0

ProductのSupplierプロパティはオプションです.ProductはSupplier以外の別のオブジェクトによって所有されています。何をお勧めしますか?結合クラス? – roryf

関連する問題