Spring JPA Repository调用findAll返回空列表,MySQL表有数据如何排查?
问题根因优先级排查
1. 多数据源配置缺失核心组件(最高概率)
你当前配置了双数据源,但仅定义了crawler数据源的DataSource实例,没有为其配置对应的**LocalContainerEntityManagerFactoryBean和JpaTransactionManager**,也没有在@EnableJpaRepositories中绑定这两个组件。Spring Data JPA默认会使用主数据源(你配置的users对应的H2内存库)操作,H2库中没有对应数据自然返回空列表。
修复方案:在CrawlerDomainConfig中补充以下配置:
@Bean public LocalContainerEntityManagerFactoryBean crawlerEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("secondDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("cs.crawler.server.projectcs.domain.crawlerdb") .persistenceUnit("crawlerPersistenceUnit") // 加载JPA相关配置,比如驼峰命名、DDL策略等 .properties(jpaProperties()) .build(); } @Bean public PlatformTransactionManager crawlerTransactionManager( @Qualifier("crawlerEntityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) { return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory.getObject())); } // 加载application.yml中的JPA配置 private Map<String, Object> jpaProperties() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(false); Map<String, Object> props = new HashMap<>(); props.put("hibernate.ddl-auto", "none"); props.put("hibernate.show_sql", true); // 你原有yml中的其他jpa属性也可以在这里补充 return props; }
同时修改@EnableJpaRepositories注解绑定组件:
@EnableJpaRepositories( basePackages = "cs.crawler.server.projectcs.repos.crawlerdb", entityManagerFactoryRef = "crawlerEntityManagerFactory", transactionManagerRef = "crawlerTransactionManager" )
2. 配置变量名冲突导致数据源连错
你两个数据源的url、username、password都复用了同一个环境变量JDBC_DATABASE_URL、JDBC_DATABASE_USERNAME、JDBC_DATABASE_PASSWORD,如果运行环境中存在这三个变量,两个数据源会使用相同的配置,最终都连到H2库或者其他错误的库。
修复方案:修改crawler数据源的环境变量名,避免和主数据源冲突:
crawler: url: ${JDBC_CRAWLER_DATABASE_URL:jdbc:mysql://VPSIPHERE:3306/darcweb?createDatabaseIfNotExist=false} username: ${JDBC_CRAWLER_DATABASE_USERNAME:root} password: ${JDBC_CRAWLER_DATABASE_PASSWORD:mypassword}
3. 实体类与表/字段映射不匹配
- 表名映射错误:默认Hibernate会将
Requests实体映射到requests表,如果你的MySQL中实际表名不是这个,需要在实体类上加@Table(name = "实际表名") - 字段类型不匹配:你实体类中
is_html定义为char类型,如果MySQL中该字段是tinyint/bit类型,会导致映射失败,JPA会跳过该条数据,最终返回空列表。建议将实体类中is_html改为Boolean类型适配MySQL的tinyint(1) - 命名策略冲突:你实体类属性直接使用下划线命名(如
url_id)不符合Java驼峰命名规范,若开启了Hibernate下划线转驼峰命名策略,会导致属性和字段映射错误,建议将实体类属性改为驼峰命名(如urlId),并在yml中开启命名策略:spring: jpa: hibernate: naming: physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
4. 快速排查验证手段
在yml中添加以下配置开启JPA SQL日志:
spring: jpa: show-sql: true properties: hibernate: format_sql: true
调用接口后查看控制台打印的SQL语句,将SQL放到MySQL Workbench中执行:
- 如果SQL执行有结果:说明是实体映射问题,对照检查字段类型、名称即可
- 如果SQL执行无结果:说明是数据源连接错误,确认连接的库、表是否正确
内容的提问来源于stack exchange,提问作者Ronny Giezen
相关产品推荐
相关产品推荐

