java - Spring数据cassandra中的生命周期事件onBeforeSave是否存在错误?
问题描述
我已经按照描述实现了这个生命周期事件,以便在持久化之前对实体进行一些修改。
发布的代码是我无法发布的真实代码的简化,但这应该更好地解释这种情况。(真实的通过java反射做set部分,但是打印出来的结果是一样的)
@Override
public void onBeforeSave(BeforeSaveEvent<Person> event) {
super.onBeforeSave(event);
System.out.println("onBeforeSave");
System.out.println(event.getStatement());
System.out.println(event.getSource());
event.getSource().setName("Edited");
System.out.println("after setName");
System.out.println(event.getStatement());
System.out.println(event.getSource());
}
@Override
public void onAfterSave(AfterSaveEvent<Person> event) {
super.onAfterSave(event);
System.out.println("onAfterSave");
System.out.println(event.getSource());
}
Person
定义如下:
public class Person {
private String name;
// default getter, setter and constructor....
}
在我尝试保留此人的运行中,此代码导致
onBeforeSave
INSERT INTO person (name) VALUES ('Original');
Person{name: "Original"}
after setName
INSERT INTO person (name) VALUES ('Original');
Person{name: "Edited"}
onAfterSave
Person{name: "Edited"}
传入的实体onBeforeSave
已正确传递给onAfterSave
方法,因此如果我在第一个中进行一些更改,它将传递给第二个。底层查询和持久化值是调用之前的实体值onBeforeSave
,因此如果方法中的实体发生某些更改onBeforeSave
,这些将不会被持久化,并且底层查询在执行前不会更新。
在方法executeSave
中,回调调用的返回值(更新后的值entityToSave
)不会在下一行传递doExecute
。这将运行上一个查询。我不知道这是否是一种期望的行为,但我认为一开始链接的wiki中的一个或者这个实现是错误的。
我也尝试编辑语句,但我找不到在方法中操作其映射值的onBeforeSave
方法。有没有办法做到这一点?
我是唯一一个发现这个问题的人吗?我找不到关于此的任何问题,此时我真的需要onBeforeSave
它将按照文档中的描述工作(能够在持久化之前修改实体)。
编辑 2021-06-01:
现在,我在编写自己的CassandraTemplate
实现时取得了不错的成绩。我分享结果代码。它没有经过优化(它在每次编辑后多次运行查询生成功能,但它似乎按预期工作)
private <T> EntityWriteResult<T> executeSave(T entity, CqlIdentifier tableName, Function<T, Statement> fz,
Consumer<WriteResult> resultConsumer) {
maybeEmitEvent(new BeforeSaveEvent<>(entity, tableName, fz.apply(entity)));
T entityToSave = maybeCallBeforeSave(entity, tableName, fz.apply(entity));
WriteResult result = getCqlOperations().execute(new StatementCallback(fz.apply(entityToSave)));
resultConsumer.accept(result);
maybeEmitEvent(new AfterSaveEvent<>(entityToSave, tableName));
return EntityWriteResult.of(result, entityToSave);
}
在此代码fz
中表示查询生成功能。之前的这一代是在原始类的其他部分完成的,并且将语句传递给该方法。我改为传递函数本身,因此该方法可以在onBeforeSave
.
希望这会有所帮助。
解决方案
推荐阅读
- r - 如何使用 R 中另一个数据集的值替换一个数据集中的值?
- graphql - 如何在一个请求中使用不同的参数多次运行一个突变?
- javascript - 无法从 React Native App 的项目文件夹中导入 .js 文件
- c - 从回调(mqtt)访问配置
- python - 从文件中删除多个新行到 1 个新行
- python - 从 CSV 文件中提取包含另一个 CSV 文件中的任何值的行
- php - 数组中的语法错误
- reactjs - Expo Camera 仅使用 React Navigation 打开一次
- c++ - QLayout 和离散小部件表示 - 如何?
- php - Symfony,学说:加载通过表单更改的实体的旧值