java - Spring boot在单元测试中删除实体导致StaleStateException:批量更新从更新返回意外的行数
问题描述
我正在使用 Spring Boot (2.1.4) 并尝试编写一个简单的单元测试来删除一个实体。实体(为简洁起见省略了某些部分):
@Entity
@Table(name = "my_table")
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@Getter
@Type(type="uuid-char")
@Column(name = "attribute_id", unique = true, nullable = false)
protected UUID attributeId;
@Version
protected Date version;
@Getter
@Column(unique = true, nullable = false)
protected String value;
}
该实体有一个简单的存储库:
public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Long> {
Optional<MyEntity> findByMyId(UUID id);
}
单元测试使用内存数据库:
spring:
jpa:
database: H2
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create
properties:
hibernate.cache.use_second_level_cache: false
hibernate.cache.use_query_cache: false
generate-ddl: true
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false
username: sa
password: sa
driver-class-name: org.h2.Driver
测试本身(使用database-rider):
@Test
@DataSet(value = INITIAL, transactional = true)
void delete() {
Optional<MyEntity> v = repository.findByMyId(SECOND.getAttributeId());
assertThat(v.isPresent()).isTrue();
repository.delete(v.get());
v = repository.findByMyId(SECOND.getAttributeId());
}
测试的最后一行抛出以下异常:
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:67)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:54)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3480)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3737)
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:99)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478)
保存和查找的所有其他测试都按预期工作,只有使用删除会导致这种情况。
我已经尝试了其他帖子中的几个建议的解决方案(这是一个类似的帖子,但它没有解决我的问题)
解决方案
您是否尝试过使用@ExpectedDataSet?通过这种方式,您可以让 dbrider 在测试执行后断言数据库的状态:
@Test
@DataSet(value = INITIAL, transactional = true)
@ExpectedDataSet("expected.yml")
void delete() {
Optional<MyEntity> v = repository.findByMyId(SECOND.getAttributeId());
assertThat(v.isPresent()).isTrue();
repository.delete(v.get());
//v = repository.findByMyId(SECOND.getAttributeId()); let dbrider assert that for you
}
推荐阅读
- vispy - 如何使用 vispy 创建图像动画
- html - Bootstrap 登录和注册页面是一样的
- .net - 如何模拟服务层中使用的 SignalR
- liferay - 是否可以将 Web 内容更改记录为审核事件?
- python-3.x - 有没有办法创建一个可以学习和忘记类似于口袋妖怪的动作的功能?
- c# - AddAuthenticationSchemes 使用 OR,有没有办法让它使用 AND?
- r - 使用 dplyr 管道将列中的最小值或最大值等统计信息返回到行中
- python - 如何在 Python 中读取嵌套的结构 Parquet 文件?
- python - CV2 计算像素错误
- c# - Skiasharp旋转图像内存不足