1

私はそのような2つのエンティティを持っています(関連するものだけに蒸留されています):

public class Person {
    public virtual Address Address
}

public class Address {
}

Personは と多対 1 の関係にありAddress、オブジェクト用語では、 a は をPerson参照してAddressおり、このリンクは単方向です (Addressには への参照はありませんPerson)。

さて、このコードを使用すると:

// save a new person with a new address
var person = new Person();
person.Address = new Address();
person.Save();

// change the person's address and save it again
person.Address = new Address();
person.Save();

最初の部分は、想定されていることを実行し、データベースに newPersonとnew を作成Addressします。

ただし、2 番目の部分は既存の を更新しPersonて新しい を作成しますAddressが、孤立した最初のアドレスは削除しません。新しいエンティティへの参照を変更していることを NHibernate に認識させ、孤立したエンティティを自動的に「ガベージ コレクション」するにはどうすればよいですか? または、これを手動で行う必要がありますか?

考えられる解決策

これが実際に起こっていることの決定的な証拠はありませんが、この問題の理由は、オブジェクト リレーショナル インピーダンスの不一致によるものだと思います。プログラミングでは、オブジェクトが他のオブジェクトへの参照を保持していることを知っています。これらの参照が失われると、ガベージ コレクションが行われ、それらを指す参照がなくなった「孤立した」オブジェクトが削除されます。私が提供した例でPersonは、 への参照がありAddress、 への参照Addressが失われると、他Personsにも参照がないと仮定して、ガベージ コレクションが行われます。

データベース側では、ガベージ コレクションの概念はありません。データベースには、1 対多または多対多の関係、つまり、子のコレクションを持つ親のみが存在します。と に戻るPersonと、これは からまでAddressの 1 対多の関係であることがわかります(各人は 1 つの住所しか持つことができませんが、住所は、共通の住所を共有する人々の世帯など、多くの人に属することができます)。データベースは、親とを子のコレクションと見なします。したがって、 a を削除しても、も削除されるべきではないことは理にかなっています (別の言い方をすれば、本のコレクションを含む本棚がある場合、本を削除しても本棚は削除されません)。AddressPersonAddressPersonPersonAddress

では、これを修正するにはどうすればよいでしょうか。子コレクションが空の親を削除する必要があります。この場合、Addressの空のコレクションを持つ をPersons削除する必要があります。これはビジネス ルールです。 が単独で存在できないとは何も述べていAddressませんが、私が開発しているアプリケーションでは、 がAddress人に関連付けられていなければ意味がないため、削除する必要があります。ただし、他の誰かがやって来てそれを参照するまで、アドレスが孤立した状態のままになる可能性は十分Personにあります。

4

2 に答える 2

1

リレーションシップに cascade="all-delete-orphan" を設定します

于 2010-01-09T05:26:44.640 に答える
1

一方の (アドレス) 側から関係をマップしたとしても、Hibernate でこれを行う合理的な方法はありません。これは、子コレクションの 1 つが空になったときにオブジェクトを自動的に削除するように要求することと同じです。考えられる解決策についてはあなたの考えには従いませんが、これはビジネス ルールであることは間違いありません。

もちろん、これを達成するための「悪い」方法もあります。データベースに外部キー制約がある場合、参照を変更して例外を飲み込むときに Address を削除できます。削除が成功した場合、それは孤児であり、そうでない場合は、それを参照している人物がまだ存在します。

Address は通常、リレーションシップの多側にあります。つまり、Person は複数のアドレスを持つことができます。これは、イモ、はるかに優れたアプローチです。Address テーブルに重複したアドレスが表示されますが、これは重複データではなく繰り返しデータとして発生します。

于 2010-01-10T13:05:48.937 に答える