spring-data-mongodb 中没有“_class”属性的对象的默认实现映射
Default implementation mapping for object without "_class" attribute in spring-data-mongodb
我有下一个问题:在项目开始时,我只有一个实现 class:
class Wrapper {
private Child child;
}
class Child { ... }
并且当 mongodb 序列化此 class 时,它从未为 child
对象设置 _class
属性。
现在我需要制作下一个 classes 结构:
class Wrapper {
private Child child;
}
abstract class Child { ... }
class ChildA extends Child { ... }
class ChildB extends Child { ... }
显然,然后我尝试反序列化旧文档,它抛出异常,因为它无法实例化抽象 class。
问题是:有没有办法指定对象反序列化的默认实现?例如,如果 Jackson 库中的 this 参数不存在 _class
属性,我想将 child
字段反序列化为 Child1
class?
这可能不是最佳解决方案,因为我怀疑有办法控制 mongo 反序列化。但是,如果您想避免挖到那口井,您可以使用 Mongo lifecycle events 之一。特别是,onAfterLoad 在从数据库中读取文档之后,但在它被转换为 java 对象之前调度。
因此,使用该事件,您可以检查传入的 json,甚至可以在它转换之前对其进行更改...这是您的情况的示例:
@Component
public class WrapperRepositoryListener extends AbstractMongoEventListener<Wrapper> {
@Override
public void onAfterLoad(AfterLoadEvent<Wrapper> event) {
Document doc = event.getDocument();
Document child = (Document)doc.get("child");
if (!child.containsKey("_class")) {
child.put("_class", "ChildA");
}
}
}
或者,(虽然我知道这不是你问的问题),根据你有多少数据,你可以编写一个 mongodb 脚本来简单地更新所有现有记录拥有 _class 字段:
db.wrappers.update(
{
"child" : { $exists : true},
"child._class" : { $exists : false }
},
{
$set:{
"child._class" : "ChildA"
}
},
{
multi: true,
upsert: false
}
)
我有下一个问题:在项目开始时,我只有一个实现 class:
class Wrapper {
private Child child;
}
class Child { ... }
并且当 mongodb 序列化此 class 时,它从未为 child
对象设置 _class
属性。
现在我需要制作下一个 classes 结构:
class Wrapper {
private Child child;
}
abstract class Child { ... }
class ChildA extends Child { ... }
class ChildB extends Child { ... }
显然,然后我尝试反序列化旧文档,它抛出异常,因为它无法实例化抽象 class。
问题是:有没有办法指定对象反序列化的默认实现?例如,如果 Jackson 库中的 this 参数不存在 _class
属性,我想将 child
字段反序列化为 Child1
class?
这可能不是最佳解决方案,因为我怀疑有办法控制 mongo 反序列化。但是,如果您想避免挖到那口井,您可以使用 Mongo lifecycle events 之一。特别是,onAfterLoad 在从数据库中读取文档之后,但在它被转换为 java 对象之前调度。
因此,使用该事件,您可以检查传入的 json,甚至可以在它转换之前对其进行更改...这是您的情况的示例:
@Component
public class WrapperRepositoryListener extends AbstractMongoEventListener<Wrapper> {
@Override
public void onAfterLoad(AfterLoadEvent<Wrapper> event) {
Document doc = event.getDocument();
Document child = (Document)doc.get("child");
if (!child.containsKey("_class")) {
child.put("_class", "ChildA");
}
}
}
或者,(虽然我知道这不是你问的问题),根据你有多少数据,你可以编写一个 mongodb 脚本来简单地更新所有现有记录拥有 _class 字段:
db.wrappers.update(
{
"child" : { $exists : true},
"child._class" : { $exists : false }
},
{
$set:{
"child._class" : "ChildA"
}
},
{
multi: true,
upsert: false
}
)