【发布时间】:2022-02-28 22:09:24
【问题描述】:
在我的应用程序中,我使用 Hibernate 和 Spring Data 将测量数据导入数据库。源可以为具有现有数据库数据的时间戳提供数据,以便进行修改。因此,在重新写入条目之前,该时间段内的所有条目(由源数据给出)都将被删除。
对于现有数据,我在saveAll() 上收到此异常:
“行已被另一个事务更新或删除”(或未保存值映射不正确)
但是,应该在 same 事务中删除该行,我希望 Hibernate 明白它必须重新INSERT 条目而不是执行UPDATE。
存储库方法由 Spring Data 提供。这是我的代码的简化版本:
@Transactional(rollbackFor = Exception.class)
private void import(List<Entry> entries) {
// ...
this.measurementRepo.removeAllByTimeIsBetween(firstDt, lastDt);
this.measurementRepo.saveAll(measurements);
}
这里有什么问题?这是不允许的吗?还是认为这两个操作都属于一个事务是错误的假设?但是,它应该可以工作,即使有两个事务。有时间问题吗?是否保证操作按给定顺序执行?是不是 Spring Data 的问题?
我不能在两个单独的事务中执行这些操作(如果这可能是一个解决方案),因为我只想在确定也插入新行的情况下删除行。
我解决此问题的想法是检测现有行并对具有匹配时间戳的条目执行更新而不是删除。我不确定这是否可行。
【问题讨论】:
-
你是如何进行删除和保存的?如果您纯粹使用托管实体,它应该可以工作,您可以从
persistent到removed并返回,但如果您混合其他操作,它可能会混淆。另外,数据库获取 DELETE 和 INSERT 是硬性要求,还是在休眠级别进行优化就可以了? -
我只调用 Spring Data 存储库方法。甚至
remove...方法也是由 Spring Data 自动实现的。删除/插入不是硬性要求。实际上是这样写的,以使其尽可能简单。检查条目是否已存在比将它们全部删除更复杂且容易出错。
标签: spring hibernate spring-data-jpa spring-data spring-transactions