【发布时间】:2021-01-13 13:24:06
【问题描述】:
我已经学习了许多教程并查看了许多答案(在 SO 和其他站点中),并且我非常有信心我没有错过任何内容,但是我无法让两个数据源/EntityManagers 在我的环境中工作。
这就是我所拥有的
DbADataSourceConfig.java
package com.myorg.rest.config.dba;
import ...
@Configuration
// @EnableJpaRepositories(
// basePackages = "com.myorg.rest.dao.dbA",
// entityManagerFactoryRef = "dbAEntityManager",
// transactionManagerRef = "dbATransactionManager"
// )
@EnableTransactionManagement
public class DbADataSourceConfig {
@Autowired
private EnvProperties settings;
@Bean
@Primary
public DataSource prjDataSource() {
DataSourceProperties ds = settings.getdbADatasource();
return ds.initializeDataSourceBuilder().type(BasicDataSource.class).build();
}
@Bean(name = "dbAEntityManager")
@Primary
public LocalContainerEntityManagerFactoryBean dbAEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(prjDataSource());
em.setPackagesToScan(new String[] { "com.myorg.model.entities.dba" });
em.setPersistenceUnitName("dbAUnit");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
// em.afterPropertiesSet();
return em;
}
@Bean(name = "dbATransactionManager")
@Primary
public PlatformTransactionManager dbATransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(dbAEntityManager().getObject());
return transactionManager;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
}
}
DbBDataSourceConfig.java
package com.myorg.rest.config.dbb;
import ...
@Configuration
// @EnableJpaRepositories(
// basePackages = "com.myorg.rest.dao.dbB",
// entityManagerFactoryRef = "dbBEntityManager",
// transactionManagerRef = "dbBTransactionManager"
// )
@EnableTransactionManagement
public class DbBDataSourceConfig {
@Autowired
private EnvProperties settings;
@Bean
@Primary
public DataSource prjDataSource() {
DataSourceProperties ds = settings.getdbBDatasource();
return ds.initializeDataSourceBuilder().type(BasicDataSource.class).build();
}
@Bean(name = "dbBEntityManager")
@Primary
public LocalContainerEntityManagerFactoryBean dbBEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(prjDataSource());
em.setPackagesToScan(new String[] { "com.myorg.model.entities.dbb" });
em.setPersistenceUnitName("dbBUnit");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
// em.afterPropertiesSet();
return em;
}
@Bean(name = "dbBTransactionManager")
@Primary
public PlatformTransactionManager dbBTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(dbBEntityManager().getObject());
return transactionManager;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
}
}
AbstractDBADAO.java
package com.myorg.rest.dao.dba.base;
public abstract class AbstractDBADAO<T extends Serializable> implements IAbstractJpaDAO<T> {
private Class<T> clazz;
@PersistenceContext(unitName = "dbAUnit")
private EntityManager entityManager;
public AbstractDBADAO(Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
public T findOne(String id) {
return entityManager.find(clazz, id);
}
public List<T> findAll() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> entityQuery = criteriaBuilder.createQuery(clazz);
entityQuery.from(clazz);
return entityManager.createQuery(entityQuery).getResultList();
}
public void create(T entity) {
entityManager.persist(entity);
}
public T update(T entity) {
return entityManager.merge(entity);
}
public void delete(T entity) {
entityManager.remove(entity);
}
public void deleteById(String entityId) {
T entity = findOne(entityId);
delete(entity);
}
}
最后一个 IAbstractJpaDAO.java
package com.myorg.rest.dao.dba.base;
import ...
public interface IAbstractJpaDAO<T extends Serializable> {
T findOne(String id);
List<T> findAll();
void create(T entity);
T update(T entity);
void delete(T entity);
void deleteById(String entityId);
}
当然,还有一堆@Repositorys 扩展IAbstractDAO 接口和相应的一堆@Services 扩展AbstractDAO<T>,但这些只是骨架之类的
EntityARepo.java
package com.myorg.rest.dao.dba.repositories;
import ...
@Repository
public interface EntityARepo extends IAbstractJpaDAO<EntityA> {
}
EntityAService.java
package com.myorg.rest.dao.dba.services;
import ...
@Service
public class EntityAService extends AbstractDBADAO<EntityA> implements EntityARepo {
public EntityAService() {
super(EntityA.class);
}
}
同样,为第二个数据库 (dbB) 设置了一大堆类。
问题
无论我做什么,我都会遇到以下问题(或非常相似的问题):
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected single matching bean but found 2: org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework.orm.jpa.SharedEntityManagerCreator#1
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1285)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
据我了解,@PersistenceContext 无法解析为正确的LocalContainerEntityManagerFactoryBean。他们都有setPersistenceUnitName('dbXUnit'),所以他们应该能够正确解决,对吧?
我没有任何persistence.xml 文件,我正在以编程方式进行所有操作。
到目前为止我已经尝试过什么
- 显然,上面的代码。
- 另外,您会注意到
@EnableJpaRepositories的评论部分;这也不起作用。 - 我还尝试为每个 DataSource 配置类构建一个
PersistenceUnitManager,但没有成功。 - 我试过
@Autowired,有没有@PersistenceContext,也没有运气。 - 我已经在 setter 上尝试了
@PersistenceContext,并在输入EntityManager上使用了@Qualifier,但也没有运气。 - 我尝试过使用和不使用
@Primary装饰器。
请记住,上面发布的文件之间的任何不一致肯定是复制/粘贴错误,为了保密,我不得不编辑名称。另请注意,我编译、运行的代码除了上面列出的错误外,不会输出任何其他错误。此外,只设置了其中一个数据库配置类,项目按预期运行,我可以在该连接上执行测试。
问题
- 谁能发现为什么
@PersistenceContext没有接线 正确的依赖并抱怨重复?或 - 我应该以完全不同的方式做事吗?
【问题讨论】:
标签: spring-boot jpa spring-data-jpa entitymanager