3

私は本質的にコレクションの負荷の単なるラッパーである Hibernate クラスを持っています。

したがって、クラスは(大幅に単純化/疑似)次のようになります。

@実在物  
パブリック クラス MyClass {

  @OneToMany  
  マップ1

  @OneToMany  
  マップ2

  @OneToMany   
  マップ3

  AddToMap1();  
  AddToMap2();  
  AddToMap3();  
  RemoveFromMap1();  
  RemoveFromMap2();  
  RemoveFromMap3();  
  DoWhateverWithMap1();  
  DoWhateverWithMap2();  
  DoWhateverWithMap3();  

}

これらの各マップには、それに関連付けられたいくつかのメソッドがあります (追加/削除/尋問/など)。

ご想像のとおり、10 番目のコレクションを追加する頃には、クラスのサイズは少しばかげています。

私がやりたいのは、次のようなものです。

 
@実在物  
パブリック クラス MyClass {

  ClassWrappingMap1;

  ClassWrappingMap2;

  ClassWrappingMap3;
}

さまざまなメソッドがすべてこれらのクラスにまとめられています。

パブリック クラス ClassWrappingMap1 {

  @OneToMany
  地図

  AddToMap();  
  RemoveFromMap();  
  DoWhateverWithMap();  

}

おそらくこれを使用できると思い@Embeddedましたが、機能させることができないようです (Hibernate は、wrapperClass 内で Map を永続化しようとさえしません)。

誰かがこれまでにこのようなことをしたことがありますか? ヒントはありますか?

どうもありがとう、
ネッド

4

2 に答える 2

2

注釈の Hibernate マニュアルには、次のように記載されています。

EJB3 仕様ではサポートされていませんが、Hibernate Annotations を使用すると、組み込み可能なオブジェクト (つまり、@*ToOne または @*ToMany) で関連付けアノテーションを使用できます。関連付け列をオーバーライドするには、@AssociationOverride を使用できます。

したがって、ラッピングアプローチが機能するはずです。


まず、関連するエラーがないか、すべてのログ ファイルなどを確認する必要があります。

次のようなことを試すことができます:

  • マスタークラス ( MyClass )
@実在物  
パブリック クラス MyClass {

  @埋め込み
  ClassWrappingMap1 map1;
}
  • そしてあなたのラッピングクラスで
@埋め込み可能
パブリック クラス ClassWrappingMap1 {

  @OneToMany
  マップ map1;

}

注釈をClassWrappingMap1使用していることに注意してください。@Embeddableただし、ドキュメントによると、@Embeddable アノテーションは必要ありません。@Embedded アノテーションを使用する場合はデフォルトにする必要があります。

すべての ClassWrappingMap クラスがデータベース内の異なる列をマップしていることを確認してください。@Idまた、ClassWrappingMap クラスには、主キー (または@EmbeddedId列)があってはなりません。

于 2009-12-12T13:29:58.300 に答える
0

ラッパー クラスを使用するときのデフォルトの戦略はわかりませんが、Hibernate Interceptor を使用してonLoadメソッドをオーバーライドすることでラッパーを初期化できます。何かのようなもの

public class WrapperInterceptor extends EmptyInterceptor {

    private Session session;

    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        if (entity instanceof MyClass) {
             MyClass myClass = (MyClass) entity;

             Query query = session.createQuery(<QUERY_TO_RETRIEVE_WRAPPED_ENTITY_GOES_HERE>);

             WrappedEntity wrappedEntity = query.list().get(0);

             myClass.setWrapperClass(new WrapperClass(wrappedEntity));
        }
    }

    public void setSession(Session session) {
        this.session = session;
    }
}

次のことを処理します。

このインターセプターを使用するクライアントは、Session プロパティを設定する必要があります

したがって、コードは次のようになります

WrapperInterceptor interceptor = new WrapperInterceptor();

Session session = sessionFactory().openSession(interceptor);

Transaction tx = session.beginTransaction();

interceptor.setSession(session);

MyClass myClass = (MyClass) session.get(newItem, myClassId); // Triggers onLoad event

tx.commit();
session.close();

または、Spring AOP を使用して同じタスクを実行します。Spring と Hibernate を使用したドメイン駆動設計を参照してください。

別の戦略を知っている場合は、私たちと共有してください。

よろしく、

于 2009-12-12T18:43:47.340 に答える