2016-04-19 25 views
0

zu deklarieren Ich verwende Spring Boot (1.3.3) mit Annotation-basierte/JavaConfig-Konfiguration für eine Anwendung. Ich habe folgende Repository-Schnittstelle:Spring Boot: Wie eine benutzerdefinierte Repository-Factory-Bean

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

} 

Was würde ich tun möchte, ist das Verhalten einiger Methoden in den generierten Repository Proxy außer Kraft setzen. Die einzige Art, wie ich dies zu tun gefunden basieren auf, was die Dokumentation schlägt vor, für das Hinzufügen von neuen kundenspezifischen Methoden (siehe: Adding custom behavior to single repositories), so definiere ich die folgende Schnittstelle:

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

... und ich füge Sie die entsprechende Umsetzung:

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; 
    } 

} 

Nun, wenn ich die Anwendung zu starten, erhalte ich folgende Fehlermeldung:

... 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.() ...

Frage: Wie kann ich die BeanInstantiationException lösen? Ich nehme an, ich muss eine Repository-Factory-Bean deklarieren, aber ich bin mir nicht sicher, wie dies die Spring Boot-Konfiguration überschreibt.

Antwort

4

der Tat müssen Sie einen neuen FactoryBean in Ihrer @EnableJpaRepositories Anmerkung erklären:

@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; 
     } 
    } 
} 

Dann wird es Ihre SimpleJpaRepository Beispiel sein: SimpleJpaRepositoryImpl die

verwendet wird
+0

Ich habe dies versucht und es wurde immer noch versucht, den Standardkonstruktor für SomethingRepositoryImpl zu instanziieren. Das liegt daran, dass Spring standardmäßig Klassennamen abruft, die auf Impl enden. Ich habe das Impl-Suffix geändert und den von Ihnen bereitgestellten Code hinzugefügt, und es hat funktioniert. – Nicolas

+0

Würde dieser Ansatz funktionieren, wenn ich mehr als ein Repository anpassen müsste? Sieht so aus, als ob Sie nur eine repositoryFactoryBeanClass in @EnableJpaRepositories definieren können. – Nicolas

+0

Ja, weil repositoryFactoryBeanClass Ihnen erlaubt, auf Ihre benutzerdefinierte SimpleJpaRepository-Instanz zu zeigen, die von allen Ihren Repositorys geteilt wird. –

Verwandte Themen