4

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

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

这些当然是不可访问的,因为ChildRepositoryImplimplementsChildCustomRepository而不是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

那么,如何才能做到这一点呢?

4

3 回答 3

2

ApplicationContextAware我知道的一种解决方案是在类中实现接口ChildRepositoryImpl并像applicationContext.getBean(<bean name>). 我不想实现这一点,但这是我目前知道的唯一选择。

于 2012-11-22T01:27:05.143 回答
1

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

例如,假设您想将自定义方法添加到

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
    }
}
于 2018-10-19T12:40:15.983 回答
0

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

于 2013-04-05T11:19:03.600 回答