如何在Spring项目中使默认EntityManager bean来自@Primary EntityManagerFactory?

问题描述 投票:0回答:1

场景:

我有一个应用程序扩展了另一个应用程序,因此其中有 2 个

DataSource
和 2 个
EntityManagerFactory
。第一个
EntityManagerFactory
是为原始应用程序创建的,第二个是在我的扩展中创建和使用的。正在扩展的应用程序使用许多自己的 jar,我不考虑修改原始应用程序 jar 中的任何代码。

Bean 定义:


@Bean("em1")
@Primary
@PersistenceContext(unitName = "pc1")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        @Qualifier("ds1") DataSource dataSource) {
    LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
    retVal.setDataSource(myDataSource);
    retVal.setJpaProperties(Properties.getJpaProperties());
    return retVal;
}


@Bean(name = "em2")
@PersistenceContext(unitName = "pc2")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        @Qualifier("ds2") DataSource dataSource) {
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    emf.setDataSource(dataSource);
    emf.setPersistenceXmlLocation("classpath:persistence/persistence.xml");
    return emf;
}

问题:

我可以通过使用

 成功从课程中的第二个学生中获得 
EntityManager

@PersistenceContext(unitName = "pc2")
protected EntityManager entityManager; 

但是,当原始应用程序尝试通过

 在其库之一中获取 
EntityManager

@Autowired
private EntityManager myEntityManager;

它抛出一个

NoUniqueBeanDefinitionException
表示它发现了 2 个类型为
EntityManager

的 bean

问题:

如何让我的

@Primary
EntityManagerFactory
创建一个也默认使用的
EntityManager
?或者我可以采取什么其他解决方案来修复这些冲突的bean而不修改原始应用程序?

java spring spring-data-jpa autowired entitymanager
1个回答
0
投票

我遇到了同样的问题,并通过创建一个标记为 @Primay @Bean 的默认 EntityManager 来解决它

    @Primary
    @Bean(name = "entityManager")
    public EntityManager sharedEntityManager(@Qualifier("entityManagerFactory") EntityManagerFactory emf) {
        return SharedEntityManagerCreator.createSharedEntityManager(emf);
    }

我正在使用 @Bean Qualified 作为“entityManagerFactory”。 @Primary 注释强制

@Autowired EntityManager em
使用此主要 EnityManager。

如果我想使用其他EntityManager,我可以使用@Quulifier注释,如下所示:

@Autowired @Qualifier("entityManagerBeanNumberTwo") EntityManager em

SharedEntityManagerCreator:

Delegate for creating a shareable JPA EntityManager reference for a given EntityManagerFactory
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/jpa/SharedEntityManagerCreator.html

完整配置:

@Primary
@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "entityManagerFactory",
    basePackages = {"my.package.domain"},
    transactionManagerRef = "transactionManager"
)
@Profile({"test", "default"})
public class TestDatabaseConfiguration {
    @Primary
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                       @Qualifier("dataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("my.package.domain")
            // with this you can make proxy injection by @PersistenceContext(unitName="domain")
            .persistenceUnit("domain")
            .build();
    }

    @Primary
    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager(
        @Qualifier("entityManagerFactory") @Autowired EntityManagerFactory entityManagerFactory
    ) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Primary
    @Bean(name = "entityManager")
    public EntityManager sharedEntityManager(@Qualifier("entityManagerFactory") EntityManagerFactory emf) {
        return SharedEntityManagerCreator.createSharedEntityManager(emf);
    }
}

原答案: https://stackoverflow.com/a/77070851/9950085 来自 Spring 团队成员的信息: https://github.com/spring-projects/spring-framework/issues/15076#issuecomment-1634307435

© www.soinside.com 2019 - 2024. All rights reserved.