从 Spring/MongoDB findAndModify 返回新旧实体
Returning both old and new entities from Spring/MongoDB findAndModify
我们通过 Spring 数据使用 MongoDB 并依靠 findAndModify
操作来更新现有实体或创建新实体。
在 findAndModify
中,我们可以配置为 return 实体的旧状态或使用 returnNew(...)
的新状态。
有什么方法可以 return 来自 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
中已经做过的事情。
我们还考虑过先加载一个旧实例,然后 运行 更新,但这并不安全,因为实体可能在加载和更新之间被修改。这可以通过版本和乐观锁定来解决,但这会使事情变得更加复杂。
Is there some way to return both old and new entities from findAndModify?
否,没有办法 return 旧值和新值 findAndModify
。
不,无法使用 findAndModify return 旧值和新值。
但是如果你想比较更新前后的实体状态,请执行以下步骤
- 在更新之前使用主键检索数据并存储在 oldData 变量中
- 在您的 findAndModify 查询中将 returnNew 更改为 true 以将其保存在 newData
下
下面的示例 sudocode 将 return 你的两个值
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 = findById(); //query to retrieve existing data
final Data newData = operations.findAndModify(findById, update,
FindAndModifyOptions.options().upsert(true).returnNew(true), Data.class);
return new Pair<Data>(oldData, newData);
}
我们通过 Spring 数据使用 MongoDB 并依靠 findAndModify
操作来更新现有实体或创建新实体。
在 findAndModify
中,我们可以配置为 return 实体的旧状态或使用 returnNew(...)
的新状态。
有什么方法可以 return 来自 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
中已经做过的事情。
我们还考虑过先加载一个旧实例,然后 运行 更新,但这并不安全,因为实体可能在加载和更新之间被修改。这可以通过版本和乐观锁定来解决,但这会使事情变得更加复杂。
Is there some way to return both old and new entities from findAndModify?
否,没有办法 return 旧值和新值 findAndModify
。
不,无法使用 findAndModify return 旧值和新值。
但是如果你想比较更新前后的实体状态,请执行以下步骤
- 在更新之前使用主键检索数据并存储在 oldData 变量中
- 在您的 findAndModify 查询中将 returnNew 更改为 true 以将其保存在 newData 下
下面的示例 sudocode 将 return 你的两个值
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 = findById(); //query to retrieve existing data
final Data newData = operations.findAndModify(findById, update,
FindAndModifyOptions.options().upsert(true).returnNew(true), Data.class);
return new Pair<Data>(oldData, newData);
}