【问题标题】:How to use my base repository methods in custom implementation repository in Spring-Data-JPA?如何在 Spring-Data-JPA 的自定义实现存储库中使用我的基本存储库方法?
【发布时间】:2012-07-15 02:14:27
【问题描述】:

我遵循了创建和自定义存储库的参考指南并提出了以下建议:

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

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(
        EntityManager entityManager) {

        return new MyBasicRepositoryFactory<T, I>(entityManager);
    }

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

        private EntityManager entityManager;

        public AlisDaoFactory(EntityManager entityManager) {
        super(entityManager);

            this.entityManager = entityManager;
        }

        @Override
        protected Object getTargetRepository(RepositoryMetadata metadata) {

            return new AlisDaoImpl<T, I>((Class<T>) metadata.getDomainType(),
                entityManager);
        }

        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {

            // The RepositoryMetadata can be safely ignored, it is used by the
            // JpaRepositoryFactory
            // to check for QueryDslJpaRepository's which is out of scope.
            return MyBasicRepository.class;
        }
}





@NoRepositoryBean
public interface MyBasicRepository<T extends MyEntity, KEY extends Serializable> extends CrudRepository<T, KEY> {

    void customBaseFoo(T entity);

}

public interface ChildCustomRepository{

    void customChildFoo();
}

public interface ChildRepository extends MyBasicRepository<Child, Integer>, ChildCustomRepository {

    void findByName(String name);
}

现在关于customChildFoo() 的实现,我想打电话给ChildRepository.findByName 或者甚至可能是MyBasicRepository.customBaseFoo()

这些当然是不可访问的,因为 ChildRepositoryImpl 实现了 ChildCustomRepository 而不是 ChildRepository,否则我还必须为基本的 CRUD 和自定义接口编写实现。

所以我尝试将ChildRepository 注入到 Impl 中:

public class ChildRepositoryImpl implements ChildCustomRepository{
    @Resource
    private ChildRepository base;

    @Override
    public void customChildFoo(){
        Child child = base.findByName();
        // do some logic with found child here
        base.customBaseFoo(child);            
    }

但它失败的原因是: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'childDao': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:109) at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1442) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:848) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:438) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:549) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) ... 65 more Caused by: java.lang.NullPointerException at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:125) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:41) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) ... 78 more

那么,如何实现呢?

【问题讨论】:

    标签: java spring-data-jpa


    【解决方案1】:

    我知道的一个解决方案是在ChildRepositoryImpl 类中实现接口ApplicationContextAware 并像applicationContext.getBean(&lt;bean name&gt;) 一样读取bean。 我不想实现这个,但这是我目前知道的唯一选择。

    【讨论】:

      【解决方案2】:

      您必须非常小心地命名以避免循环引用。

      例如,假设您要添加自定义方法

      UserDAO
      

      为此,您需要创建一个名为

      的新存储库接口
      UserDAOCust
      

      然后,为了能够在您的 UserDAOCust 实现中使用 UserDAO 存储库方法,您的实现必须命名为:

      UserDAOImpl
      

      并将 UserDAO 作为片段的成员注入。

      (通过阅读 Spring JPA 文档,您似乎必须将您的实现命名为 UserDAOCustImpl,但这实际上会导致循环引用)

      完整源代码(在 Kotlin 中):

      @Repository
      interface UserDAO : CrudRepository<User, Int>, UserDAOCust
      {}
      
      interface UserDAOCust
      {
          fun findByType(): Optional<List<User>>
      }
      
      class UserDAOImpl : UserDAOCust
      {
          @Autowired
          private lateinit var userDAO: UCUserDAO
      
          override fun findByType(): Optional<List<User>>
          {
              // use this.userDAO here
          }
      }
      

      【讨论】:

        【解决方案3】:

        可以将父存储库注入自定义实现,它对我有用。但我没有使用任何RepositoryFactoryBean 来自定义我的存储库。目前使用 Spring Data JPA 1.3.0,也许你应该尝试使用最新版本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-09
          • 2018-10-06
          • 1970-01-01
          • 1970-01-01
          • 2017-03-26
          • 2014-02-02
          • 2015-03-15
          • 1970-01-01
          相关资源
          最近更新 更多