在Spring Data JPA存储库中使用@Primary [英] Using @Primary in Spring Data JPA repositories

查看:135
本文介绍了在Spring Data JPA存储库中使用@Primary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果有人需要在Spring Data存储库上使用@Primary,请执行以下操作: 看起来Spring Data JPA会忽略存储库上的@Primary批注.

If someone ever needed to use @Primary on Spring Data repositories: It looks like Spring Data JPA ignores @Primary annotations on repositories.

作为一种解决方法,我创建了BeanFactoryPostProcessor,它检查给定的存储库是否具有@Primary批注并将该bean设置为主.

As a workaround I have created BeanFactoryPostProcessor which checks if given repository has @Primary annotation and sets that bean as primary.

这是代码:

@Component
public class SpringDataPrimaryPostProcessor implements BeanFactoryPostProcessor {
    public static final String REPOSITORY_INTERFACE_PROPERTY = "repositoryInterface";


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        makeRepositoriesPrimary(getRepositoryBeans(beanFactory));
    }

    protected List<BeanDefinition> getRepositoryBeans(ConfigurableListableBeanFactory beanFactory) {
        List<BeanDefinition> springDataRepositoryDefinitions = Lists.newArrayList();
        for (String beanName : beanFactory.getBeanDefinitionNames()) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);

            String beanClassName = beanDefinition.getBeanClassName();
            try {
                Class<?> beanClass = Class.forName(beanClassName);
                if (isSpringDataJpaRepository(beanClass)) {
                    springDataRepositoryDefinitions.add(beanDefinition);
                }
            } catch (ClassNotFoundException e) {
                throw new ApplicationContextException(String.format("Error when trying to create instance of %s", beanClassName), e);
            }
        }

        return springDataRepositoryDefinitions;
    }

  protected void makeRepositoriesPrimary(List<BeanDefinition> repositoryBeans) {
    for (BeanDefinition repositoryBeanDefinition : repositoryBeans) {
        String repositoryInterface = (String) repositoryBeanDefinition.getPropertyValues().get(REPOSITORY_INTERFACE_PROPERTY);
            if (isPrimary(repositoryInterface)) {
                log.debug("Making site repository bean primary, class: {}", repositoryInterface);
                repositoryBeanDefinition.setPrimary(true);
            }
    }
}

protected boolean isSpringDataJpaRepository(Class<?> beanClass) {
    return RepositoryFactoryInformation.class.isAssignableFrom(beanClass);
}

private boolean isPrimary(String repositoryInterface) {
    return AnnotationUtils.findAnnotation(getClassSafely(repositoryInterface), Primary.class) != null;
}

    private Class<?> getClassSafely(String repositoryInterface) {
        try {
            return Class.forName(repositoryInterface);
        } catch (ClassNotFoundException e) {
            throw new ApplicationContextException(String.format("Error when trying to create instance of %s", repositoryInterface), e);
        }
    }

推荐答案

我尝试将解决方案应用于具有两个Mongo存储库的Spring Boot应用程序. 但是它无法在propertyValues中找到repositoryInterface. 进一步的调查表明,有一个属性可以标识存储库接口factoryBeanObjectType.

I tried applying the solution to spring boot application having two Mongo repositories. But it was not able to find repositoryInterface in propertyValues. Further investigation revealed that there is an attribute to identify the repository interface factoryBeanObjectType.

因此,从以下位置更改方法makeRepositoriesPrimary()中的代码:

So changing the code in method makeRepositoriesPrimary()from:

String repositoryInterface = (String) repositoryBeanDefinition.getPropertyValues().get(REPOSITORY_INTERFACE_PROPERTY);

收件人:

String repositoryInterface = (String) repositoryBeanDefinition.getAttribute("factoryBeanObjectType");

按预期工作.

希望这会有所帮助.

这篇关于在Spring Data JPA存储库中使用@Primary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆