【发布时间】:2016-09-13 12:59:29
【问题描述】:
我们通过 Spring Data 使用 MongoDB,并依靠 findAndModify 操作来更新现有实体或创建新实体。
在findAndModify 中,我们可以配置返回实体的旧状态或使用returnNew(...) 的新状态。
有没有办法从findAndModify返回新旧实体?
我们需要比较更新前后的实体状态,这就是我们需要两个实例的原因。
目前我们使用requireNew(false),然后手动更新旧实例的副本,如下所示:
public Pair<Data> saveItems(String id, List<Item> items) {
final Query findById = ...;
final Update update = new Update();
// This is what we actually update
update.set(ENTITY_FIELD_ITEMS, newItems);
update.inc(ENTITY_FIELD_VERSION, 1);
// Try updating and return the old data
final Data oldData = operations.findAndModify(findById, update,
FindAndModifyOptions.options().upsert(true).returnNew(false), Data.class);
// Copy or create new instance
final Data newData;
if (oldData == null) {
newData = new Data(id);
}
else {
newData = new Data(oldData);
}
// Apply the same update
newData.setItems(newItems);
newData.incVersion();
return new Pair<Data>(oldData, newData);
}
有效,但不是很漂亮,因为我们必须在旧实例的副本上重做我们在 Update 中所做的相同操作。
我们还考虑过首先加载旧实例并运行更新,但这并不安全,因为实体可能已在加载和更新之间进行了修改。这可以通过版本和乐观锁定来解决,但这会使事情变得更加复杂。
【问题讨论】:
标签: spring mongodb mongodb-query spring-data mongodb-java