gpt4 book ai didi

java - Spring Boot 自动从错误的数据源生成表

转载 作者:行者123 更新时间:2023-12-02 11:11:00 25 4
gpt4 key购买 nike

我当前的项目需要连接多个数据库。我设置了

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update

application.properties中。

我有一些 dbConfig 如下:

@Configuration
public class DBSourceConfiguration {
public final static String DATA_SOURCE_PRIMARY = "dataSource";
public final static String DATA_SOURCE_PROPERTIES = "propertiesDataSource";
public final static String DATA_SOURCE_REPORT = "reportDataSource";
public final static String DATA_SOURCE_NEW_DRAGON = "newDragonDataSource";

@Primary
@Bean(name = DATA_SOURCE_PRIMARY)
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = DATA_SOURCE_REPORT)
@ConfigurationProperties(prefix = "externaldatasource.report")
public DataSource reportDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = DATA_SOURCE_NEW_DRAGON)
@ConfigurationProperties(prefix = "externaldatasource.newdragon")
public DataSource newDragonDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = DATA_SOURCE_PROPERTIES)
@ConfigurationProperties(prefix = "externaldatasource.properties")
public DataSource propertiesDataSource() {
return DataSourceBuilder.create().build();
}
}

<!-- language: Java -->

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = PrimaryDbConfig.ENTITY_MANAGER_FACTORY,
transactionManagerRef = PrimaryDbConfig.TRANSACTION_MANAGER,
basePackageClasses = { _TbsRepositoryBasePackage.class })
public class PrimaryDbConfig extends AbstractDbConfig {
public final static String ENTITY_MANAGER_FACTORY = "entityManagerFactoryPrimary";
public final static String ENTITY_MANAGER = "entityManagerPrimary";
public final static String TRANSACTION_MANAGER = "transactionManagerPrimary";

@Autowired
@Qualifier(DBSourceConfiguration.DATA_SOURCE_PRIMARY)
private DataSource dataSource;

@Primary
@Bean(name = ENTITY_MANAGER_FACTORY)
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSource).properties(getVendorProperties(dataSource)).packages(_TbsEntityBasePackage.class).persistenceUnit("primaryPersistenceUnit").build();
}

@Primary
@Bean(name = ENTITY_MANAGER)
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactory(builder).getObject().createEntityManager();
}

@Primary
@Bean(name = TRANSACTION_MANAGER)
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactory(builder).getObject());
}
}

<!-- language: Java -->

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = PropertiesDbConfig.ENTITY_MANAGER_FACTORY,
transactionManagerRef = PropertiesDbConfig.TRANSACTION_MANAGER,
basePackageClasses = { _PropertiesRepositoryBasePackage.class })
public class PropertiesDbConfig extends AbstractDbConfig {
public final static String ENTITY_MANAGER_FACTORY = "entityManagerFactoryProperties";
public final static String ENTITY_MANAGER = "entityManagerProperties";
public final static String TRANSACTION_MANAGER = "transactionManagerProperties";

@Autowired
@Qualifier(DBSourceConfiguration.DATA_SOURCE_PROPERTIES)
private DataSource dataSource;

@Bean(name = ENTITY_MANAGER_FACTORY)
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSource).properties(getVendorProperties(dataSource)).packages(_PropertiesEntityBasePackage.class).persistenceUnit("propertiesPersistenceUnit").build();
}

@Bean(name = ENTITY_MANAGER)
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactory(builder).getObject().createEntityManager();
}

@Bean(name = TRANSACTION_MANAGER)
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactory(builder).getObject());
}
}

还有两个 DBConfig 类(就像上面的两个 DbConfig 类一样)。

我的问题是每次运行这个网络应用程序时,实体(在不同的包下)都会生成到所有数据库。换句话说,Tbs(Primary)实体将为newDragon和所有其他数据库生成表。

例如,实体 A 属于主数据源,实体 B 属于属性数据源。但框架会为主数据库newDragon数据库以及其他两个数据库生成表A、B。

<小时/>

更新 2018/06/01 - 1

虽然框架生成所有数据库的所有实体,但我仍然可以从正确的数据库访问表。我的所有网络应用程序功能都运行良好。这很奇怪,不是吗?

我想我的配置很好,因此我的应用程序访问数据库时不会出现任何问题(例如从错误的数据库读取并获得空结果或将数据插入错误的数据库等)。可能还有其他原因导致此 gernerte 所有表到所有数据库问题。

最佳答案

根据您提供的配置,来自正确数据库的 CRUD 表应该不会有问题。但是将表生成到正确的数据库中,有时您可能需要检查配置是否正确选择实体/包名称。

每个LocalContainerEntityManagerFactoryBean都设置有唯一的包类,框架将扫描该包名下的实体并在目标数据源生成相应的表;但是,有一种情况 packageToScan 会被更改。由于您有 @EntityScan 注释,它会
覆盖所有定义的LocalContainerEntityManagerFactoryBean上的packagesToScan,引用代码如下:EntityScanRegistrar.java

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LocalContainerEntityManagerFactoryBean) {
LocalContainerEntityManagerFactoryBean factoryBean = (LocalContainerEntityManagerFactoryBean) bean;
factoryBean.setPackagesToScan(this.packagesToScan);
this.processed = true;
}
return bean;
}

因此,即使您为每个 LocalContainerEntityManagerFactoryBean 提供了唯一的包类,如果您在应用程序中的某个位置使用了 @EntityScan,最终结果仍可能会被框架覆盖。您的配置对我来说似乎没问题,因此首先尝试查找并解析 @EntityScan 和 LocalContainerEntityManagerFactoryBean 之间的包名称,它应该可以解决问题。

引用:https://github.com/spring-projects/spring-boot/issues/6830

关于java - Spring Boot 自动从错误的数据源生成表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50621404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com