0

まず、私は Hibernate の専門家ではありません。私は他のプロジェクトでその基本のみを使用しました。しかし今、レガシー データベース スキームで Hibernate を使用したいのですが、テーブルを Java ドメイン モデルにマップする際にいくつかの問題が発生しています。

1) 多くのテーブルには、ユーザーが割り当てた主キー (文字列として) があります。したがって、それらは何らかのアルゴリズムに従って生成されません。実際、それらは Hibernate が「自然な」キーと呼ぶものです。ユーザーによって割り当てられた ID を受け入れるように Hibernate に指示する方法はありますか?

2) 2 番目の問題は、多くのテーブルに、valid_from、valid_to、date_created、date_last_modified、user_last_modified、user_created などの共通のプロパティがあることです。これらのプロパティは、監査 (どのレコードがどのユーザーによって変更されたか) に使用され、'valid_to' 日付フィールドが過去の場合にレコードを無効にします。これらのフィールドは「メタデータ」のように見えるため、エンド ユーザーに公開したくありませんが、これらのフィールドを更新する方法を見つける必要があります。レコードが変更されるたびにこれらのフィールドを更新するために使用できる Hibernate の一般的なソリューションはありますか? 参考までに、これらのフィールドは、2 つのテーブル間の多対多の関係を管理するために使用される「リンク テーブル」でも使用されます。

すべてのヘルプは非常に高く評価されています!

更新: AbstractEntity を使用して共通のプロパティを保持し、EventListener を使用してこれらのフィールドを挿入/更新します。ユーザーは UserContext.getCurrentUser() によって取得されます (ユーザーは ThreadLocal を使用して現在のスレッドにバインドされます)。

現在の唯一の問題は、これらの「関連付け」テーブルを処理する方法です...それらにはこれらの共通フィールドも含まれており、そのような関連付けテーブルをマップする別のクラスを作成したくありません。私の意見では、Hibernate はこのようなリンク テーブルを隠すのに優れています。このようなリンク テーブルを EventListener で更新する方法はありますか?

たとえば、テーブル A がリンク テーブル A_B を介してクラス B と多対多の関係を持っている場合、A または B でレコードが挿入/更新されるたびに A_B を更新する方法はありますか?

4

1 に答える 1

1

JPA アノテーションを使用してマッピングを宣言していると思います。

最初の問題。@GeneratedValue注釈を適用しないでください。

public class SomeEntityWithAutogeneratedId {
    @Id
    @GeneratedValue // autogeneration
    private Long id;
}

public class SomeEntityWithoutAutogeneratedId {
    @Id
    private String id;
}

2番目の問題。基本クラスを準備して、共通フィールドのマッピングを簡素化できます。次に、@PrePersist更新前に必要なすべてのフィールドに正しい値を適用するために使用できます。

public abstract class AbstractEntity {

    @Column
    private Date dateLastModified;

    @PrePersist
    public void beforePersist() {
        this.dateLastModified = new Date();
    }
}

public class Entity1 extends AbstractEntity {
public class Entity2 extends AbstractEntity {
public class Entity3 extends AbstractEntity {
...
public class EntityN extends AbstractEntity {

一般に、Hibernate を介してレガシー データベースを使用する場合は、コードの記述を開始する前に、テーブル構造/関係を確認し、適切な変更を行うことをお勧めします。これにより、多くの時間を節約できます。たとえば、次のようにしたほうがよいでしょう。

  • 複合キーを自動生成された一意の識別子に置き換えます(説明については、公式ドキュメントのこのエントリを参照してください)
  • すべてのトリガーまたはストアド プロシージャを削除/休止状態機能または Java コードで置き換えます。すべてのロジックがアプリケーション コードにある場合は、キャッシュ機能を簡単に使用できます。
  • 今のところ他のことは想像できませんが、非常に長いリストを持つことができます。なぜなら、SQL データベースは、Hibernate 経由では簡単に使用できないより多くの機能/機能を提供するからです。
于 2013-08-09T11:22:55.027 に答える