1

マークされた行がコンパイルされないため、次のコードは (もちろん) 機能しません。

MyClass {
    //singleton stuff
    private static MyClass instance;
    private MyClass () {}
    public static MyClass getInstance() {
        if(instance==null) {
            instance = new MyClass ();
        }
        return instance;
    }

    // method creating problems
    public NonGenericSuperClassOfGenericClass create(Class<?>... classes) {
        if(someCondition)
             return new GenericClass<classes[0],classes[1]>; // DOES NOT COMPILE
        else
             return new OtherGenericClass<classes[0]>;
    }
}

したがって、「作成」が返されるかどうかは実際にはわかりません

GenericClass<classes[0],classes[1]>

また

OtherGenericClass<classes[0]>

パラメータの数が異なります。

これは、Springを使用していてMongoDBを使用する予定であるために発生しますが、将来的には別のもの (Hibernate など) に切り替える必要があるかもしれません。

クラス GenericClass は次のようなものです。

 GenericClass<PersistetType1, Long> 

また

 GenericClass<PersistentType2, Long>

ここで、PersistentType1/2 は最終的に DB に格納する必要があるクラスであり、GenericClass は Mongo API にアクセスするための一種のプロキシです。実際には、次のようになります。

  public MongoTemplate getTemplate();
  public void save(T toInsert);
  public List<T> select(Query selectionQuery);
  public T selectById(ID id);
  public WriteResult update(Query selectionQuery, Update updatedAttributes);
  public void delete(T toRemove);
  public void delete(Query selectionQuery);

それで?コントローラ (またはうるさい場合はエンティティ) から、リポジトリをインスタンス化し、任意のメソッドを呼び出す必要があります。これにより、コントローラーは MongoDB と結合されます。つまり、コントローラーは、実際には MongoRepository と呼ばれ、Mongo に厳密に依存する GenericClass を明示的にインスタンス化する必要があります (実際、これは正確に 2 つの「自由度」を持つジェネリックです)。

そこで、コントローラーを分離する別のプロキシである MyClass を作成することにしました。このようにして、Controller は MyClass の単一のインスタンスを取得し、適切なリポジトリの新しいインスタンスを作成できるようにします。特に、「somecondition」が true の場合は、MongoRepository を使用することを意味します (false の場合、Hibernate プロキシ、つまり HibernateRepository をインスタンス化する必要がある可能性があります)。ただし、MongoRepository は汎用であるため、パラメーターとして渡すことを望んでいたインスタンス化の何らかの形式が必要です。

残念ながら、ジェネリックはコンパイル時に解決されるため、私には機能しないと思います。

どうすれば修正できますか?

4

1 に答える 1

2

基礎となる永続ストアをアプリケーション ロジックから切り離すために、DAO アプローチを使用します。

save、update などの必要なメソッドを使用して、DAO のインターフェイスを定義します。次に、必要な各永続化プロバイダーの実装を提供します。egUserAccess は、HibernateUserAccess および MongoUserAccess として実装できるインターフェイスである可能性があります。各実装では、Mongo や Hibernate などの適切なテンプレートを挿入し、それを使用して永続化操作を完了します。

発生する可能性のある問題は、ロード操作が User のインスタンスを返すことです。これは、永続化プロバイダー間で異なる必要があります。つまり、JPA アノテーションは、MongoDB に必要な Spring Data アノテーションとは異なります (漏れのある抽象化)。

おそらく、永続化操作の結果を表すユーザー インターフェイスを作成し、永続化プロバイダーごとに実装することで、これを解決するでしょう。それか、JPA または Mongo ロードの結果から構築した共通モデルを返します。

于 2012-06-30T11:57:17.830 に答える