2012-09-05 12 views
11

MongoDBデータベースにProductsというコレクションがあります。このコレクションは、JavaコードのIProductPriceというインタフェースで表されています。次のリポジトリ宣言により、Spring Dateはコレクションdb.collection: Intelliprice.iProductPriceを参照します。SpringデータのクラスのMongoDbコレクション名を設定する方法

@Collection(..)注釈をIProductPriceに置くのではなく、外部設定を使用してdb.collection: Intelliprice.Productsを表示するように設定する必要があります。これは可能ですか?これどうやってするの?あなたが現在これを達成することができます

public interface ProductsRepository extends 
    MongoRepository<IProductPrice, String> { 
} 

答えて

10

唯一の方法はに永続化されなければならない、このクラスのコレクションのインスタンスの名前を定義するためにcollectionプロパティを使用して@Documentであなたのドメインクラスに注釈を付けることです。

しかし、クラス、コレクション、およびプロパティ名をよりグローバルに処理する方法を設定するためのプラグイン可能な名前付け戦略を追加することを示唆するJIRA issueが公開されています。あなたのユースケースにコメントして投票してください。

+1

ありがとう、私は@Documentアノテーションを認識しており、おそらくそれを使用して終了します。私は基本的に、実際のクラスから設定を外部化したかったのです。リンクしたJIRAの問題はネーミング戦略について話していますが、カスタム名の注釈を使用することを提案しています。 – Danish

+1

'collection'属性はSpELをサポートしています。例えば、'#{#bean.someMethod(T(your.fully.qualified.Type)}} 'を使って他のSpring Bean上で任意のメソッドを呼び出してコレクション名を計算することができます。 'someMethod(Class type)'メソッドを提供するコンポーネントを 'bean 'として登録しました。 –

6

上記のOliver Gierkeの回答を使用して、 私は1つのエンティティに対して複数のコレクションを作成する必要があるプロジェクトに取り組んでいます。私はスプリングレポジトリを使いたいので、リポジトリを使用する前に使用するエンティティを指定する必要がありました。

このシステムでは、SPeLを使用して、要求に応じてリポジトリコレクション名を変更することができました。あなたは一度に1つのコレクションだけで作業することができます。

ドメインオブジェクト

@Document(collection = "#{personRepository.getCollectionName()}") 
public class Person{} 

デフォルトスプリングリポジトリ:

public interface PersonRepository 
    extends MongoRepository<Person, String>, PersonRepositoryCustom{ 
} 

カスタムリポジトリインタフェース:

public interface PersonRepositoryCustom { 
    String getCollectionName(); 

    void setCollectionName(String collectionName); 
} 

実装:

public class PersonRepositoryImpl implements PersonRepositoryCustom { 

    private static String collectionName = "Person"; 

    @Override 
    public String getCollectionName() { 
     return collectionName; 
    } 

    @Override 
    public void setCollectionName(String collectionName) { 
     this.collectionName = collectionName; 
    } 
} 

それを使用するには:

@Autowired 
PersonRepository personRepository; 

public void testRetrievePeopleFrom2SeparateCollectionsWithSpringRepo(){ 
     List<Person> people = new ArrayList<>(); 
     personRepository.setCollectionName("collectionA"); 
     people.addAll(personRepository.findAll()); 
     personDocumentRepository.setCollectionName("collectionB"); 
     people.addAll(personRepository.findAll()); 
     Assert.assertEquals(4, people.size()); 
} 

を使用すると、コンフィギュレーション変数を使用する必要がある場合はそうでなければ、多分このようなものを使用することができますか? source

@Value("#{systemProperties['pop3.port'] ?: 25}") 
+0

はこれをテストしておらず、あまりクリーンではありませんが、創造的な意味で+1しています:) – alex

+0

さまざまな場所で自動配線される可能性のあるリポジトリ内に「コンテキスト」情報を保持しているようです。私の推測では、このソリューションはスレッドセーフではありません。 – thanosa75

+0

@ thanosa75あなたは正しいですが、私はその解決法を再利用していて、コレクション名を常に提供するリポジトリを持つことは、repo.findAll()> repo.findAll( "collectionName")ではなく、ずっと安全です。 私はその方法をわかりません(mongoテンプレートを再利用するクラスを再作成するのではなく、要求を実行する前にコレクション名を常に設定します) – Jeremie

関連する問題