2016-11-24 7 views
2

データベースの設計上、かなりの数のJpaRepository拡張リポジトリインタフェースがあります。Spring Data:複数のリポジトリの1つの「リポジトリ」サービスクラスへのインタフェース

単純なオブジェクト、すなわちPersonを構築するには、データがデータベース全体にそのように広がっているため、約4 - 5リポジトリへのメソッド呼び出しを行う必要があります。このような何か(擬似コードのための恩赦):

@Service 
public class PersonConstructService { 

    public PersonConstructService(Repository repository, 
            RepositoryTwo repositoryTwo, 
            RepositoryThree repositoryThree) { 

     public Person constructPerson() { 
      person 
       .add(GetDataFromRepositoryOne()) 
       .add(GetDataFromRepositoryTwo()) 
       .add(GetDataFromRepositoryThree()); 

      return person; 
     } 

     private SomeDataTypeReturnedOne GetDataFromRepositoryOne() { 
      repository.doSomething(); 
     } 

     private SomeDataTypeReturnedTwo GetDataFromRepositoryTwo() { 
      repositoryTwo.doSomething(); 
     } 

     private SomeDataTypeReturnedThree GetDataFromRepositoryThree() { 
      repositoryThree.doSomething(); 
     } 
    } 
} 

PersonConstructServiceクラスは、単純なPersonオブジェクトを構築するために、すべてのこれらのインターフェイスを使用しています。私はこれらのリポジトリをPersonConstructServiceクラス内のさまざまなメソッドから呼び出すことにしています。私はこのクラスを複数のクラスに広げることを考えましたが、これは正しいとは思いません。

代わりにPersonオブジェクトの作成に必要なすべてのリポジトリを含むrepositoryServiceを使用します。それは良いアプローチですか?春には可能ですか?

私が尋ねる理由は、クラスに注入されたサービスの数が時々約7-8であるということです。これは間違いなく良いことではありません。

+0

Springでは、あなたのクラスですぐにサービスを利用できるようにするために、まず '@ Autowired'アノテーションを使用することができますが、' PersonConstructService'クラスからリポジトリメソッドを直接呼び出すべきではありません。それは問題ではありません。クラス内で7つのサービスが必要な場合、なぜこれらの7つのサービスを呼び出すのが悪いのですか?あなたのPOJOが( '@ ManyToOne'、' @ OneToMany'、...)のような関係で結ばれているかどうかは、手動で他のものを手作業で追加することなく単純に作ることができると思います。 – Alex

+0

@Alexあなたのクラスコンストラクタで、理解しているように、Spring Docsによると、多くのサービスがあるとします。「副次的なことに、コンストラクタ引数の多くは悪いコードの匂いです。あなたはこれを使ってフィールドインジェクションを提案していますか?\t 'Springでは、あなたのクラスであなたのサービスをすぐに利用できるように、@Autowiredアノテーションを使用することができます'? –

+0

はい、まあまあです。コンストラクタの引数は大事なことですが、あなたのサービスは、あなたが望むものを適切に行う別の方法です。 Java EEはすでにv6でこれを '@ Inject'で実装していますが、Springの公式キーワードは' @ Autowired'です。私は自分のクラスのうちのいくつかを人格的に6または7個持っています。 – Alex

答えて

2

私はあなたが/ shoudlが抽象化のようなメタリポジトリを作成することはできないと思います。リポジトリは明確に定義された意味を持ちますが、概念的にはHibernate/JPA/Datastoreエンティティ用のCRUDサービスです(そして時には:-))。そして、これで十分です。それ以上のものは混乱します。

ここで私が提案するのは、Personオブジェクトの意味に寄与する新しいサービスを自動的に認識する「Person」オブジェクトを構築する「スマートな」方法です。

それの核心は、その次のようになります。

  • あなたのリポジトリが指定されたインターフェイスを実装可能性があり、方法を持っていると思われる、PersonDataProvider言う、public PersonPart contributeDataToPersonBuidler(PersonBuilder)を言います。
  • あなたはあなたの@Service実装はその後になり
  • How to collect and inject all beans of a given type in Spring XML configurationで受け入れ答えを参照してください)あなたの@Serviceは、あなたがそのようなすべてのPersonDataProviderインスタンスのコンテナを検査し、あなたのサービスにそれらを注入することができ、春のBeanFactoryPostProcessorインターフェイスを実装するだろうすべてのPersonDataProviderにデータの提供を依頼してください。

私は少し拡大することができましたが、これは私が行く方法が好きです。

これはきれいではないと主張できます(これは、サービス層で起こる「何か」をリポジトリが認識するようにする必要がありません)。しかし、それを回避することはできますが、その方法の要点。

EDIT:この記事が最初に書かれたので、私はSpringがPostProcessorsを必要とせずに特定のタイプのすべてのBeanを自動検出して注入できることに気付きました。ここで受け入れられた回答を参照してください:Autowire reference beans into list by type

0

私はそれをサービス層ではかなり合理的で実用的なデータ集約と見ています。 これはSpringで完璧に達成できます。あなたがリポジトリコードへのアクセス権を持っている場合は、それらすべてのような名前を付けることができます。

@Repository("repoOne") 
public class RepositoryOne { 

@Repository("repoTwo") 
public class RepositoryTwo { 

をし、必要に応じて集約サービスへ注入:実際には

@Service 
public class MultipleRepoService { 

    @Autowired 
    @Qualifier("repoOne") 
    private RepositoryOne repositoryOne; 

    @Autowired 
    @Qualifier("repoTwo") 
    private RepositoryTwo repositoryTwo; 

    public void doMultipleBusiness() { 
     repositoryOne.one(); 
     repositoryTwo.two(); 
    } 
} 

、あなたも名前にする必要はありませんし、彼らは別のクラスであれば、それらを修飾しますが、彼らは階層にあるか、同じインタフェースを持っている場合...

オートワイヤリングそうでない場合も、あなたが構築する方法に直接注入することができ:

public void construct(@Qualifier("repoOne")RepositoryOne repoOne, 
          @Qualifier("repoTwo")RepositoryTwo repoTwo) { 
     repoOne.one(); 
     repoTwo.two(); 
    } 
関連する問題