我想在我的Spring Boot 应用程序中实现主从DB artitechure,我只是使用2个正常的DB示例,Havent在DB级别配置了一些东西,我已经在下面列出了我的配置和错误,有人可以帮助吗?做一些配置需要在数据库级别做,因为我只是测试。请告诉我。
下面是我的DataSourceConfig:
@Configuration
public class DataSourceConfig extends HikariConfig {
@Value("${spring.entity.scan.packages}")
private String packageToScan;
@Value("${spring.datasource.master.url}")
private String masterDbUrl;
@Value("${spring.datasource.master.username}")
private String masterDbUserName;
@Value("${spring.datasource.master.password}")
private String masterDbPassword;
@Value("${master.database.maxconnection}")
private int masterDbMaxConnection;
@Value("${spring.datasource.slave.url}")
private String slaveDbUrl;
@Value("${spring.datasource.slave.username}")
private String slaveDbUserName;
@Value("${spring.datasource.slave.password}")
private String slaveDbPassword;
@Value("${master.database.maxconnection}")
private int slaveDbMaxConnection;
@Primary
@Bean(name = "masterDataSource")
public DataSource masterDataSource() {
HikariConfig masterConfig = new HikariConfig();
masterConfig.setPoolName(DataSourceConfig.class.getName()+"_master");
System.out.println(masterDbUrl);
System.out.println(masterDbUserName);
System.out.println(masterDbPassword);
System.out.println(masterDbMaxConnection);
masterConfig.setJdbcUrl(masterDbUrl);
masterConfig.setUsername(masterDbUserName);
masterConfig.setPassword(masterDbPassword);
masterConfig.setMaximumPoolSize(masterDbMaxConnection);
return new HikariDataSource(masterConfig);
}
@Bean(name = "slaveDataSource")
public DataSource slaveDataSource() {
HikariConfig slaveConfig = new HikariConfig();
slaveConfig.setPoolName(DataSourceConfig.class.getName()+"_slave");
System.out.println(slaveDbUrl);
System.out.println(slaveDbUserName);
System.out.println(slaveDbPassword);
System.out.println(slaveDbMaxConnection);
slaveConfig.setJdbcUrl(slaveDbUrl);
slaveConfig.setUsername(slaveDbUserName);
slaveConfig.setMaximumPoolSize(slaveDbMaxConnection);
slaveConfig.setPassword(slaveDbPassword);
return new HikariDataSource(slaveConfig);
}
@Bean
public DataSource routingDataSource() {
Map<Object, Object> targetDataSources = new LinkedHashMap<>();
RoutingDataSourceConfiguration routingDataSourceConfiguration = new RoutingDataSourceConfiguration();
DataSource master = this.masterDataSource();
targetDataSources.put(DataSourceTypes.MASTER, master);
DataSource slave = this.slaveDataSource();
targetDataSources.put(DataSourceTypes.SLAVE, slave);
routingDataSourceConfiguration.setTargetDataSources(targetDataSources);
routingDataSourceConfiguration.setDefaultTargetDataSource(master);
return routingDataSourceConfiguration;
}
@Bean
public DataSource dataSource() {
return new LazyConnectionDataSourceProxy(routingDataSource());
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setPackagesToScan(packageToScan);
JpaVendorAdapter vendor = new HibernateJpaVendorAdapter();
factory.setJpaVendorAdapter(vendor);
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty("hibernate.show_sql", "true");
factory.setJpaProperties(properties);
return factory;
}
@Bean
@Primary
public PlatformTransactionManager transactionManager
(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(entityManagerFactory);
return tm;
}
}
下面是我的RoutingDataSourceConfiguration:
public class RoutingDataSourceConfiguration extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
boolean isReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
logger.info(isReadOnly);
if(isReadOnly) {
return DataSourceTypes.SLAVE;
} else {
return DataSourceTypes.MASTER;
}
}
}
这是我的 www.example.com
database.db.name=db_delivery
spring.datasource.master.url=jdbc:mysql://171.46.7.224/${database.db.name}?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.master.username=user
spring.datasource.master.password=pass
spring.datasource.master.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.slave.url=jdbc:mysql://171.43.7.214/${database.db.name}?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.slave.username=user
spring.datasource.slave.password=pass
spring.datasource.slave.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = update
spring.datasource.maximum-pool-size=10
spring.jpa.properties.hibernate.jdbc.batch_size=30
master.database.maxconnection=100
spring.entity.scan.packages=com.project
server.port=8080
spring.security.user.name=System
spring.security.user.password=pass
以下是我的repo:
@Repository
public interface JobsCycleCountRepo extends JpaRepository<JobsCycleCount,Long> {
@Transactional(readOnly = true)
List<WarehouseJobsCycleCount> findAllByJobId(Long jobId);
}
以下是我的实体WarehouseJobsCycleCount:
@Entity
@Table(name = "warehouse_jobs_cycle_count")
@Data
public class WarehouseJobsCycleCount {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "job_id")
private Long jobId;
@Column(name = "sku_id")
private String skuId;
@Column(name = "location_id")
private Long locationId;
@Enumerated(EnumType.STRING)
private WarehouseJobCycleCountStatus status;
}
现在,当我通过控制器通过任何服务方法调用这个repo方法时,我会得到这样的错误:
SQL Error: 1054, SQLState: 42S22
2023-04-27 14:53:40.919 ERROR 10375 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'warehousej0_.jobId' in 'field list'
2023-04-27 14:53:41.060 ERROR 10375 --- [nio-8080-exec-1] c.d.w.exceptions.ControllerAdvisor : Custom Exception: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
2023-04-27 14:53:42.256 WARN 10375 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet]
如何解决这个问题?我已经被困在这两天,但没有任何工作。
1条答案
按热度按时间wnvonmuf1#
根据您提供的代码和错误消息,您面临的问题似乎与SQL错误有关。错误消息表明存在未知列“warehousej0_”。字段列表中的jobId'。
以下是一些建议,可帮助您调试和解决此问题:
1.验证列名:仔细检查数据库表中对应于'jobId'字段的列名。确保列名拼写正确,并且与代码中使用的列名匹配。列名和字段名之间可能存在打字错误或不匹配。
1.检查表和列Map:确保实体类(
JobsCycleCount
)中的表和列Map是准确的。确保实体类属性用适当的JPA注解(@Column
、@Table
等)正确注解。)。请特别注意'jobId'字段的Map。1.验证数据库架构:确认数据库模式是最新的,并且与实体类中定义的预期结构相匹配。确保数据库表中存在所需的列及其对应的数据类型。
1.检查数据库连接:确保应用程序可以成功连接到主数据库和从数据库。验证www.example中两个数据库的连接详细信息(URL、用户名、密码)是否正确 www.example.com 文件。
1.验证数据访问逻辑:检查存储库和服务类中的逻辑。确保正确定义查询和联接以检索所需的数据。请注意查询中可能使用的任何命名约定或别名。
1.启用SQL日志记录:在应用程序中启用SQL日志记录,以查看Hibernate正在执行的实际SQL查询。这可以帮助您识别生成的SQL语句的任何问题。您可以将以下行添加到您的www.example中 www.example.com 文件以启用SQL日志记录:
使用此配置,您将看到在控制台或日志文件中记录的SQL查询。
通过仔细检查这些方面,您应该能够识别并解决您遇到的SQL错误。如果问题仍然存在,提供实体类代码(
JobsCycleCount
)和任何相关的实体Map将有助于进一步调查问题。