2016-03-10 3 views
0

Я пытаюсь создать базовую функциональность для всех репозиториев хранения данных с пружинными данными, но настойчивую проблему.spring-data-rest, обычный настраиваемый метод для всех репозиториев

Версия весны - 4.2.4, у меня есть UserRepository, привязанный к относительной пользовательской сущности, а также UserController, управляющий логикой, связанной с несколькими репо.

Я хочу добавить собственный метод sharedCustomMethod ко всем моим репозиториям, включая UserRepository.

Я BaseRepositoryRelated классы и интерфейсы:

@NoRepositoryBean 
public interface BaseRepository <T, E extends Serializable> 
extends PagingAndSortingRepository<T, E>, BaseRepositoryCustom<T, Serializable> { 

    @Override 
    @Query("select e from #{#entityName} e where e.enabled=1 and e.id=?1") 
    T findOne(E primaryKey); 

    @Override 
    @Query("select e from #{#entityName} e where e.enabled=1") 
    Iterable<T> findAll(); 

    @Override 
    @Query("select count(*) from #{#entityName} e where e.enabled=1") 
    long count(); 

    @Override 
    @Query("update #{#entityName} e set e.enabled=0 where e.id=?1") 
    @Modifying 
    void delete(E primaryKey); 
} 

пользовательского интерфейса:

package com.eolcum.repository.base; 

import java.io.Serializable; 

import org.springframework.data.repository.NoRepositoryBean; 

@NoRepositoryBean 
public interface BaseRepositoryCustom <T, E extends Serializable> { 

    void sharedCustomMethod(E id); 
} 

Пользовательские Impl:

package com.eolcum.repository.base; 

import java.io.Serializable; 

import javax.persistence.EntityManager; 

import org.springframework.data.jpa.repository.support.SimpleJpaRepository; 
import org.springframework.transaction.annotation.Transactional; 

public class BaseRepositoryImpl<T, ID extends Serializable> 
    extends SimpleJpaRepository<T, Serializable> 
    implements BaseRepository<T, Serializable> { 

    private final EntityManager entityManager; 

    public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) { 
     super(domainClass, em); 
     this.entityManager = em; 
    } 

    @Override 
    @Transactional 
    public void sharedCustomMethod(Serializable id) { 
     System.out.println("done!"); 

    } 

} 

BaseRepo Factory Bean:

package com.eolcum.repository.base; 

import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; 
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; 
import org.springframework.data.jpa.repository.support.SimpleJpaRepository; 
import org.springframework.data.repository.core.RepositoryInformation; 
import org.springframework.data.repository.core.RepositoryMetadata; 
import org.springframework.data.repository.core.support.RepositoryFactorySupport; 

import javax.persistence.EntityManager; 
import java.io.Serializable; 

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

    @Override 
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) { 
     return new BaseRepositoryFactory(em); 
    } 

    private static class BaseRepositoryFactory<T, I extends Serializable> 
      extends JpaRepositoryFactory { 

     private final EntityManager em; 

     public BaseRepositoryFactory(EntityManager em) { 
      super(em); 
      this.em = em; 
     } 

     @Override 
     protected SimpleJpaRepository<T, Serializable> getTargetRepository(RepositoryInformation information, 
       EntityManager entityManager) { 
      return new BaseRepositoryImpl<T, I>((Class<T>) information.getDomainType(), em); 
     } 

     @Override 
     protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { 
      return BaseRepositoryImpl.class; 
     } 
    } 
} 

PersistenceContext: package com.eolcum.repository.base;

import org.springframework.context.annotation.Configuration; 
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

import com.eolcum.controller.UserController; 

@Configuration 
@EnableJpaRepositories(basePackages = {"com.eolcum.repository.base"}, 
     repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class) 
@EnableTransactionManagement 
public class PersistenceContext { 

} 

Когда я пытаюсь запустить приложение с пружинным ботинке я получаю следующее сообщение об ошибке:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.eolcum.repository.UserRepository com.eolcum.controller.UserController.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property sharedCustomMethod found for type User! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE] 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE] 
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE] 
    at com.eolcum.Application.main(Application.java:19) [classes/:na] 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.eolcum.repository.UserRepository com.eolcum.controller.UserController.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property sharedCustomMethod found for type User! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    ... 17 common frames omitted 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property sharedCustomMethod found for type User! 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    ... 19 common frames omitted 
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property sharedCustomMethod found for type User! 
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:84) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:61) ~[spring-data-jpa-1.9.2.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:95) ~[spring-data-jpa-1.9.2.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:206) ~[spring-data-jpa-1.9.2.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) ~[spring-data-jpa-1.9.2.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:416) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:206) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237) ~[spring-data-commons-1.11.2.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.9.2.RELEASE.jar:na] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
    ... 29 common frames omitted 

Благодарим за помощь заранее.

ответ

0
  1. Создать базовый интерфейс с @NoRepository аннотацию, как показано ниже:

    @NoRepositoryBean 
    public interface BaseRepository<T extends BaseModel, ID extends Serializable> 
         extends PagingAndSortingRepository<T, ID> { 
    
        T checkAsDeleted(T t); 
    
    } 
    
  2. Создать базовый класс и расширить базовый интерфейс

    @Transactional(readOnly = false) 
    public class BaseRepositoryImpl<T extends BaseModel, ID extends Serializable> 
        extends SimpleJpaRepository<T, ID> 
        implements BaseRepository<T, ID> { 
    
        public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) { 
         super(entityInformation, entityManager); 
        } 
    
        public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) { 
         super(domainClass, em); 
        } 
    
        @Override 
        public T checkAsDeleted(T t) { 
         t.setIsDeleted(true); 
         return this.save(t); 
        } 
    
        @Override 
        public <S extends T> S save(S entity) { 
         Date now = new Date(); 
         if (entity.getId() == null) { 
          entity.setCreationDate(now); 
         } 
         entity.setModifiedDate(now); 
         return super.save(entity); 
        } 
    } 
    
  3. Расширьте хранилище интерфейс с базовым интерфейсом

    @Repository 
    public interface QuestionRepository extends BaseRepository<Question, Long> { 
    
        List<Question> findByisDeleted(boolean isDeleted); 
    
        List<Question> findAll(); 
    
    } 
    
  4. Пусть знают это базовый класс для приложения

    @SpringBootApplication 
    @EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class) 
    @EnableSpringDataWebSupport 
    public class Application { 
    
        public static void main(String[] args) { 
         SpringApplication.run(Application.class, args); 
        } 
    } 
    

Теперь у вас есть checkAsDeleted() метод везде!

Все коды работают в реальном проекте