Spring Boot整合Hibernate @Transactional报无TransactionManager错误
Spring Boot集成Hibernate事务报错问题
报错信息
No qualifying bean of type 'TransactionManager' available
初始代码
最初编写的配置类与接口代码如下:
import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.springframework.context.annotation.Bean; import org.springframework.transaction.annotation.EnableTransactionManagement; @org.springframework.context.annotation.Configuration @EnableTransactionManagement public class Config { @Bean public SessionFactory sessionFactory() { Configuration configuration = new Configuration(); configuration.configure(); configuration.addAnnotatedClass(Ct.class); configuration.addAnnotatedClass(St.class); SessionFactory sessionFactory = configuration.buildSessionFactory(); return sessionFactory; } } @RestController public class RestAPIController { @Autowired private SessionFactory sessionFactory; @PutMapping("/addS") @Transactional public void addSt(@RequestParam("cc") String cc,@RequestParam("st") String st) { CC cc1= new CC(); CC.setCode(cc); State state = new State(cc,st); sessionFactory.getCurrentSession().save(state); } }
最初在
addSt方法上添加@Transactional注解,是因为之前数据库操作抛出异常时会出现The transaction was still an active报错,希望通过Spring托管事务解决该问题,但配置后出现了上述找不到TransactionManager的错误。
调整后代码
后续改用Spring Data JPA模式重构了代码,实现如下:
@Repository public interface StateRepository extends CrudRepository<State, String> {}
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.util.ArrayList; import java.util.List; @Service @Transactional public class StateService { @Autowired private StateRepository stateRepository; public void save(State state) { stateRepository.save(state); } public List<State> findAll() { List<State> states = new ArrayList<>(); stateRepository.findAll().forEach(states::add); return states; } }
问题根因与解决方法
- 初始报错核心原因:手动通过Hibernate原生
ConfigurationAPI构建SessionFactory的方式完全脱离Spring容器管理体系。@EnableTransactionManagement仅负责开启事务注解的拦截逻辑,不会自动创建事务管理器Bean;既没有手动注册HibernateTransactionManager对应的Bean,手动构建的SessionFactory也无法被Spring事务拦截器感知,不仅会抛出找不到TransactionManager的错误,之前的The transaction was still an active报错本质也是因为手动维护的SessionFactory事务生命周期没有被统一管理,出异常时事务没有被正确回滚、资源没有被释放。 - 重构方向是正确的:只要项目引入了
spring-boot-starter-data-jpa依赖,Spring Boot的自动配置会自动完成EntityManagerFactory、JpaTransactionManager等所有事务相关Bean的注册,不需要手动编写配置类构建SessionFactory。 - 规范提示:不要在Controller层直接编写数据库操作逻辑,当前把持久化逻辑放在Service层、类级别标记
@Transactional的写法符合Spring开发规范,只需要在Controller层注入StateService实例调用对应方法,事务就会被Spring自动托管,不会再出现之前的两类报错。
内容的提问来源于stack exchange,提问作者nick shetty
相关产品推荐
相关产品推荐

