1

PersonオブジェクトをDB4Oに保存したい。[個人の場所]フィールドは、時間の経過とともに変更できます。そこで、DBから人を取得し、メソッドを呼び出して、場所フィールドを新しい場所オブジェクトに設定します。(Locationオブジェクト、つまりDDD値オブジェクトを不変にしたい)。

これは機能しますが、以前に割り当てられたLocationオブジェクトはデータベースのままです。これらの孤立したLocationオブジェクトを削除するようにDB4Oを構成するにはどうすればよいですか?または、ガベージコレクションを行うためのカスタムプロセスが必要ですか?

この例の簡略化されたクラス:

class Person {
    Location location;
    public void Move(Location newLocation) { 
        location = newLocation;
    }
}

class Location {
    public Location(string city) { 
        this.City = city;
        //etc
    }
    public readonly string City;
    /// more fields...
}

編集:いくつかの詳細情報-PersonはDDD集約ルートであることが意図されています。したがって、人の内部状態への外部参照はありません。Personがその場所を更新すると、古い場所は存在しなくなります。

4

5 に答える 5

1

完璧な解決策はないと思います。しかし、いくつかの作業で、この動作をほぼ達成できます。同様のトピックはすでにここで説明されています

最初のステップは、ロケーションフィールドでカスケード削除をアクティブにすることです。したがって、個人が削除されると、場所も削除されます。

configuration.common().objectClass(Person.class).objectField("location").cascadeOnDelete(true);

次に、場所の変更の場合を処理する必要があります。アイデアはこれです:

  1. activate-eventに登録します。そこで、どのオブジェクトが埋め込まれたかを「覚えています」
  2. update-eventに登録します。そこで、それがまだ同じ埋め込みオブジェクトであるかどうかを確認します。そうでない場合は、上の古いものを削除します。
  3. 非常に重要:埋め込まれたオブジェクトを「共有」しないでください。共有しないと、すべてのユーザーが削除されます。簡単な解決策は、Locationオブジェクトが割り当てられるたびにそのコピーを作成することです。

この動作を実装するJavaデモがあります。

まあ、これは単なる概念であり、受け入れ可能な解決策への長い道のりです。

  1. 属性または他の構成を利用して、そのようなオブジェクトを指定します
  2. イベントハンドラーなどの堅牢な実装を構築します。
  3. 「共有」の場所が削除されないようにするための固溶体
于 2010-03-07T21:35:18.257 に答える
0

delete()最初に古い場所でdb4oを使用してから、新しい場所を保存するのはどうですか?

一番!

ドイツ人

于 2010-03-04T16:22:54.917 に答える
0

値型にすることを考えましたか?

于 2010-03-04T18:32:45.453 に答える
0

これは本当に私にはトランザクションのように見えます。

ドイツ語で述べたように、古いものを削除し、新しいものを保存して割り当て、これらの手順を一度に実行できることを確認する必要があります。

RDBMSでは、このためのトランザクションも考え出す必要があります。ただし、多くのRDBMSシステムは、トリガーとイベントでここでサポートします。db4oは特定のコールバックも提供することに注意してください。

私は現在、このような場合のref-countの抽象化に取り組んでいますが、一般的に処理するのは非常に難しいです。一方、Updateトランザクションを簡素化し、古いオブジェクトと新しいオブジェクトの参照を比較する特定のメソッドを作成することもできます。それらが一致せず、他の誰もそのタイプのアドレスオブジェクトを参照していないことを確認できる場合は、それを削除できます。

また、ガベージコレクションのない言語を使用している場合は、これを手動で追跡し、古いオブジェクトを削除する必要があることにも注意してください。

その「集合ルート」の概念は私には非常に曖昧に思えます-結局のところ、それは視点に依存しますが、それは別の問題です。

于 2010-03-06T10:22:55.690 に答える
0

cascadeOnDelete(boolean)のdb4o 8.0 APIリファレンスによると、古いオブジェクトは自動的に削除されるはずです。これがドキュメントのコピーです。与えられた例を確認してください。

カスケードされた削除動作を設定します。

cascadeOnDeleteをtrueに設定すると、ObjectContainer.delete(Object)に渡された場合、このクラスのインスタンスのすべてのメンバーオブジェクトが削除されます。

注意 !
この設定は、ObjectContainer.store(Object)の呼び出し時に、古いメンバーオブジェクトの削除もトリガーします。

動作の例:

ObjectContainer con;
バーbar1=new Bar();
バーbar2=new Bar();
foo.bar = bar1;
con.store(foo); //bar1はfooのメンバーとして保存されます
foo.bar = bar2;
con.store(foo); //bar2はfooのメンバーとして保存されます

最後のステートメントは、bar1への参照を保持している他の格納されたオブジェクトの数に関係なく、ObjectContainerからbar1も削除します。

デフォルト設定はfalseです。

クライアント/サーバー環境では、この設定はクライアントとサーバーの両方で使用する必要があります。

この設定は、開いているオブジェクトコンテナに適用できます。

パラメーター:
フラグ-削除をメンバーオブジェクトにカスケードするかどうか。
関連項目:
ObjectField.cascadeOnDelete(boolean)、ObjectContainer.delete(Object)、コールバックの使用

しかし、それは印刷されたようには機能せず、奇妙です。

于 2012-10-09T07:22:51.570 に答える