JpaRepository刷新后删除对象失败,如何执行回滚操作?
关联实体删除限制测试中的事务异常问题
我正在调整应用领域模型的删除逻辑:当Country关联有Region时,禁止删除该Country。测试过程中,countryRepository.flush();按预期抛出DataIntegrityViolationException,但后续调用countryRepository.count()时又再次抛出相同异常,日志显示DELETE SQL命令被重复执行。我原本以为@Transactional会自动回滚操作,但实际并未生效,推测是assertThrows捕获异常导致事务未触发回滚。
测试代码
@SpringBootTest @SpringBootApplication @TestPropertySource(locations = "classpath:unit-tests.properties") @Transactional public class Tests { @Autowired private CountryRepository countryRepository; @Autowired private RegionRepository regionRepository; @Test public void preventDeleteOfUsedObjects() { // 创建测试对象 Country country = new Country(); country.name = "United Status"; countryRepository.save(country); countryRepository.flush(); Region region = new Region(); region.name = "California"; region.country = country; regionRepository.save(region); regionRepository.flush(); // 尝试删除关联有Region的Country,预期失败 Assertions.assertThrows(DataIntegrityViolationException.class, () -> { countryRepository.delete(country); countryRepository.flush(); }); Assert.assertEquals(1, countryRepository.count()); } }
数据模型
Country实体
@Entity @Table(name = "countries") public class Country { @Id public String name; }
Region实体
@Entity @Table(name = "regions") public class Region { @Id public String name; @ManyToOne public Country country; }
数据仓库
CountryRepository
public interface CountryRepository extends JpaRepository<Country, String> { }
RegionRepository
public interface RegionRepository extends JpaRepository<Region, String> { }
测试配置文件(unit-tests.properties)
spring.datasource.url=jdbc:hsqldb:mem:model;sql.syntax_pgs=true spring.datasource.username=sa spring.datasource.password= spring.datasource.driver-class-name=org.hsqldb.jdbcDriver spring.jackson.default-property-inclusion=non_null spring.jpa.hibernate.ddl-auto=create spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE logging.level.root=INFO
Maven配置(pom.xml)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.6</version> <relativePath/> </parent> <artifactId>example</artifactId> <name>example</name> <properties> <maven.compiler.release>11</maven.compiler.release> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
内容的提问来源于stack exchange,提问作者Glorfindel
相关产品推荐
相关产品推荐

