2016-04-19 7 views
0

私はアプリケーションでアノテーションベース/ JavaConfig設定のSpring Boot(1.3.3)を使用しています。Springブート:カスタムリポジトリファクトリBeanを宣言する方法

@RepositoryRestResource(collectionResourceRel = "something", path = "something") 
public interface SomethingRepository 
    extends CrudRepository<SomethingRepository, Long> { 

} 

私は何をしたいが発生したリポジトリのプロキシの一部のメソッドの動作をオーバーライドです: は、私は、次のリポジトリのインタフェースを持っています。私はこれを行うための見つけた唯一の方法は、(参照:Adding custom behavior to single repositories)のドキュメントは、新しいカスタムメソッドを追加するための示唆ものに基づいているので、私は次のインターフェイスを定義:

public interface SomethingRepositoryCustom { 
    Something findOne(Long id); 
} 

を...と私は、対応する実装を追加します。今

public SomethingRepositoryImpl extends SimpleJpaRepository<Something, Long> 
    implements SomethingRepositoryCustom { 

    public SomethingRepositoryImpl(<Something> domainClass, EntityManager em) { 
     super(domainClass, em); 
     this.entityManager = em; 
    } 

    @Override 
    public Something findOne(Long id) { 
     System.out.println("custom find one"); 
     // do whatever I want and then fetch the object 
     return null; 
    } 

} 

私はアプリケーションを起動した場合、私は次のエラーを取得する:

... org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.dummy.repositories.SomethingRepositoryImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.dummy.repositories.SomethingRepositoryImpl.() ...

質問: BeanInstantiationExceptionを解決するにはどうしたらいいですか?リポジトリファクトリBeanを宣言する必要があると仮定していますが、Springブート設定をオーバーライドする方法がわかりません。

答えて

4

確かにあなたが@EnableJpaRepositories注釈に新しいFactoryBeanのを宣言する必要があります。

@Configuration 
@EnableJpaRepositories(value = "your_package", 
     repositoryFactoryBeanClass = CustomFactoryBean.class) 
public class ConfigurationClass{} 

CustomFactoryBean.java:

public class CustomFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I>{ 

    @Override 
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { 
     return new SimpleJpaExecutorFactory(entityManager); 
    } 

    /** 
    * Simple jpa executor factory 
    * @param <T> 
    * @param <I> 
    */ 
    private static class SimpleJpaExecutorFactory<T, I extends Serializable> extends JpaRepositoryFactory{ 

     private EntityManager entityManager; 

     /** 
     * Simple jpa executor factory constructor 
     * @param entityManager entity manager 
     */ 
     public SimpleJpaExecutorFactory(EntityManager entityManager) { 
      super(entityManager); 
      this.entityManager = entityManager; 
     } 

     @Override 
     protected Object getTargetRepository(RepositoryMetadata metadata) { 
      JpaEntityInformation entityInformation = 
        getEntityInformation(metadata.getDomainType()); 
      return new SomethingRepositoryImpl<T,I>(entityInformation, entityManager); 
     } 

     @Override 
     protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { 
      return SomethingRepositoryImpl.class; 
     } 
    } 
} 

その後、それはあなたのSimpleJpaRepositoryインスタンスになります。SimpleJpaRepositoryImpl

を使用します
+0

私はこれを試して、それはまだSomethingRepositoryImplのためのデフォルトのコンストラクタをインスタンス化しようとしていた。これは、慣習的にSpringがImplで終わるクラス名を取得するためです。 Implサフィックスを変更し、あなたが提供したコードを追加しました。 – Nicolas

+0

複数のリポジトリをカスタマイズする必要がある場合、このアプローチは機能しますか? @EnableJpaRepositoriesにはrepositoryFactoryBeanClassを1つしか定義できないようです。 – Nicolas

+0

はい、repositoryFactoryBeanClassを使用すると、すべてのリポジトリで共有されるカスタムSimpleJpaRepositoryインスタンスを指すことができます –

関連する問題