hibernate Spring Data Repositories和JdbcTemplate是否共享相同的transaction context?

vohkndzv  于 2023-06-30  发布在  Spring
关注(0)|答案(1)|浏览(140)

我很难找到关于这个主题的文件。我已经看过Spring official transactionnal handling documentation,还有一些SO帖子指向一个是的,但这不是我在实践中看到的。
考虑Sping Boot 应用程序,使用@EnableTransactionManagement@EnableJpaRepositories(使用Hibernate和Postgres)。我有以下代码:
BusinessService

@Transactional
public save(BuildingDTO dto) {
  var building = Building.from(dto);
  var apartments = Apartment.from(dto); 
  
  this.buildingRepository.save(building);
  this.saveAllJdbc(apartments);
}

private saveAllJdbc(List<Apartment> apartments) {
  String insertQuery = "...";
  jdbcTemplate.batchUpdate(
    insertQuery,
    apartments,
    100,
    (ps, apartment) -> // set ps values
  );
}

存储库定义为BuildingRepository extends CrudRepository<Building, UUID>,这意味着保存方法是事务性的。
今天我的问题是saveAllJdbc触发了外键约束,说引用的建筑不存在。这意味着它不知道当前事务。
我通过只使用Spring CrudRepository方法或只使用JdbcTemplate方法使其工作,在这两种情况下,事务都按照文档中的定义进行处理。
Spring Repository默认实现和JdbcTemplate方法应该共享事务上下文吗?或者这是一个已知的限制?

vshtjzan

vshtjzan1#

这与事务无关,与JPA的工作方式无关。
当您告诉JPA保存数据时,它不会这样做。或者至少它可以选择不这样做。相反,它只会保留对数据的引用,并最终保存它。* 最终 * 通常意味着在交易结束时。
另一方面,JdbcTemplate没有什么花哨的东西,只执行SQL语句。
正如奥利弗Drotbohm所写的,您可以通过使用JpaRepository.saveAndFlush()而不是save()触发flush事件来解决这个问题。

相关问题