使用@Transactional与@EnableTransactionManagement时遇Bean找不到问题
核心错误
paymentgateway.service.FlightBookingService中的passengerInfoRepository字段需要一个类型为'paymentgateway.repository.PassengerInfoRepository'的Bean,但未找到。
注入点带有以下注解:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
同时@Transactional注解无法正常工作,根源在于以下几个配置错误:
1. 错误排除数据源自动配置
主类上的@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})禁用了Spring Boot的数据源自动配置,而项目依赖JPA操作数据库,这直接导致JPA无法生成Repository代理Bean,事务管理器也无法初始化。
修复:
移除exclude={DataSourceAutoConfiguration.class}参数,让Spring Boot自动配置数据源和JPA相关组件。
2. 组件扫描包配置语法错误
@ComponentScan(basePackages = {"paymentgateway.repository, paymentgateway.service"})写法错误,多个包需用独立字符串元素,而非逗号拼接在单个字符串中。另外,若主类位于paymentgateway根包下,@SpringBootApplication默认会扫描根包及其所有子包,完全无需手动指定@ComponentScan,手动指定反而可能遗漏组件。
修复:
直接删除@ComponentScan注解,依赖@SpringBootApplication的默认扫描逻辑即可。
3. 配置文件名拼写错误
配置文件名为configuartio.properties,但Spring Boot仅自动加载application.properties(或yaml)作为默认配置文件,导致数据库和JPA配置完全未被加载,进一步导致JPA无法初始化Repository。
修复:
将configuartio.properties重命名为application.properties,并合并原application.properties中的server.port配置到该文件。
4. 可选优化:省略Repository注解
Spring Boot中,继承JpaRepository的接口会被自动识别为Repository Bean,无需额外添加@Repository注解,可移除该注解简化代码。
修正后的关键代码示例
主类(PaymentgatewayApplication.java)
@SpringBootApplication @RestController @EnableTransactionManagement public class PaymentgatewayApplication { private static final Logger logger = LogManager.getLogger(PaymentgatewayApplication.class); @Autowired private FlightBookingService flightBookingService; @PostMapping("/bookFlightTicket") public FlightBookingAcknowledgement bookFlightTicket(@RequestBody FlightBookingRequest flightBookingRequest) { logger.trace("Flightbooking in service: {} ", flightBookingService.bookFlightTicket(flightBookingRequest)); return flightBookingService.bookFlightTicket(flightBookingRequest); } public static void main(String[] args) { SpringApplication.run(PaymentgatewayApplication.class, args); } }
合并后的application.properties
server.port = 8081 spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/GT spring.datasource.username=said spring.datasource.password=said spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform = org.hibernate.dialect.MySQL8Dialect spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto = update spring.jpa.show-sql: true
简化后的Repository接口
public interface PassengerInfoRepository extends JpaRepository<PassengerInfo, Long> { } public interface PaymentInfoRepository extends JpaRepository<PaymentInfo, String>{ }
内容的提问来源于stack exchange,提问作者Muhammadsaied

