进行 $set 更新时未使用 Spring MongoDB Custom Converter?

发布于 2024-12-25 21:32:42 字数 3377 浏览 0 评论 0 原文

在简单示例之前进行简短的总结:

  • 插入新文档是可以的,这意味着它使用我的自定义转换器
  • 更新现有文档是不行的,这意味着它不使用我的自定义转换器

我的部门:

[INFO] +- org.springframework.data:spring-data-mongodb:jar:1.0.0.RC1:compile
[INFO] | +- org.springframework:spring-beans:jar:3.1.0.RELEASE:compile
[INFO] | +- org.springframework:spring-expression:jar:3.1.0.RELEASE:compile
[INFO] | +- org.springframework.data:spring-data-commons-core:jar:1.2.0.RC1:compile
[INFO] | | \- org.springframework:spring-tx:jar:3.1.0.RELEASE:compile
[INFO] | \- org.mongodb:mongo-java-driver:jar:2.7.1:compile

这是我的类,它具有自己的转换器

public class MyClass extends MyInterface<String> ..

以下是转换器:

public class MyClassWriteConverter implements Converter<MyClass, DBObject> {
    @Override
    public DBObject convert(MyClass myClass) {
        System.out.println("MyClass WRITE CONVERTER !");
        DBObject dbo = new BasicDBObject();
        dbo.put("title", myClass.getTitle());
        dbo.put("value", myClass.getValue());
        System.out.println("value : " + myClass.getValue());
        System.out.println("class : " + myClass.getClass().getCanonicalName());
        dbo.put("_class", myClass.getClass().getCanonicalName());
        return dbo;
    }
}
public class MyClassElementReadConverter implements Converter<DBObject, MyClass> {
    @Override
    public MyClass convert(DBObject dbObject) {
        String value = (String) dbObject.get("value");
        String title = (String) dbObject.get("title");
        return new MyClass(title, value);
    }
}

<mongo:converter>
    <bean class="kam.albert.MyClassElementReadConverter" />
</mongo:converter>
<mongo:converter>
    <bean class="kam.albert.MyClassElementWriteConverter" />
</mongo:converter>

myDomain 有一个 List>;我的类, 这工作正常,因为正在使用自定义转换器:

this.ops.save(myDomain, "myCollection");

这可以从调试输出中看到:

MyClass ELEMENT WRITE CONVERTER !
value : my value
class : kam.albert.MyClass

并且有来自我的 db.myCollection.find().pretty(); 的结果; :

{
    myClasses : [
        {
             "title" : "my title",
             "value" : "my value",
             "_class" : "kam.albert.MyClass"
        }
    ]
}

插入操作一切仍然正常...

但是当我像这样对现有文档进行 $set 更新时:

this.ops.updateFirst(
    this.idCriteria(myClass),
    new Update()
        // set the content node
        .set(dotNotation, myClass),
        "myCollection"
);

调试输出保持不变:

MyClass ELEMENT WRITE CONVERTER !
value : my value
class : kam.albert.MyClass
(edited for clarity, the other properties omitted)
DEBUG [mongodb.core.MongoTemplate]: calling update using query: { "_id" : "81d3292e-fd75-410d-a1f9-b109b6d76194"} and update: { "$
set" : { "myClasses" : [ { "title" : "my title" , "value" : "my value"}]}] } in collection: myCollection

但结果就像不使用自定义转换器,没有“_class”属性:

{
    myClasses : [
        {
             "title" : "my title",
             "value" : "my value",
        }
    ]
}

我目前的结论是:

  • 对于插入新文档,自定义转换器工作正常
  • 对于更新,虽然自定义转换器似乎被调用(调试输出在那里),但它似乎正在使用 默认的 MappingMongoConverter 来做真正的更新。

我错过了什么吗?请分享您的想法..

Short summaries before the simple examples :

  • Inserting new documents is OK, in the meaning that it uses my custom converter
  • Updating an existing document is not OK, in the meaning that it doesnt use my custom converter

My deps :

[INFO] +- org.springframework.data:spring-data-mongodb:jar:1.0.0.RC1:compile
[INFO] | +- org.springframework:spring-beans:jar:3.1.0.RELEASE:compile
[INFO] | +- org.springframework:spring-expression:jar:3.1.0.RELEASE:compile
[INFO] | +- org.springframework.data:spring-data-commons-core:jar:1.2.0.RC1:compile
[INFO] | | \- org.springframework:spring-tx:jar:3.1.0.RELEASE:compile
[INFO] | \- org.mongodb:mongo-java-driver:jar:2.7.1:compile

Here's my class that has the it's own converter

public class MyClass extends MyInterface<String> ..

Here are the the converters :

public class MyClassWriteConverter implements Converter<MyClass, DBObject> {
    @Override
    public DBObject convert(MyClass myClass) {
        System.out.println("MyClass WRITE CONVERTER !");
        DBObject dbo = new BasicDBObject();
        dbo.put("title", myClass.getTitle());
        dbo.put("value", myClass.getValue());
        System.out.println("value : " + myClass.getValue());
        System.out.println("class : " + myClass.getClass().getCanonicalName());
        dbo.put("_class", myClass.getClass().getCanonicalName());
        return dbo;
    }
}
public class MyClassElementReadConverter implements Converter<DBObject, MyClass> {
    @Override
    public MyClass convert(DBObject dbObject) {
        String value = (String) dbObject.get("value");
        String title = (String) dbObject.get("title");
        return new MyClass(title, value);
    }
}

<mongo:converter>
    <bean class="kam.albert.MyClassElementReadConverter" />
</mongo:converter>
<mongo:converter>
    <bean class="kam.albert.MyClassElementWriteConverter" />
</mongo:converter>

myDomain has a List<MyClass<?>> myClasses,
and this works fine, as the custom converter is being used :

this.ops.save(myDomain, "myCollection");

Which can be seen from the debugging output :

MyClass ELEMENT WRITE CONVERTER !
value : my value
class : kam.albert.MyClass

And has the result from my db.myCollection.find().pretty(); :

{
    myClasses : [
        {
             "title" : "my title",
             "value" : "my value",
             "_class" : "kam.albert.MyClass"
        }
    ]
}

All is still OK with the insert operation ...

But when i make $set update to an existing document like this :

this.ops.updateFirst(
    this.idCriteria(myClass),
    new Update()
        // set the content node
        .set(dotNotation, myClass),
        "myCollection"
);

The debugging output stays the same :

MyClass ELEMENT WRITE CONVERTER !
value : my value
class : kam.albert.MyClass
(edited for clarity, the other properties omitted)
DEBUG [mongodb.core.MongoTemplate]: calling update using query: { "_id" : "81d3292e-fd75-410d-a1f9-b109b6d76194"} and update: { "$
set" : { "myClasses" : [ { "title" : "my title" , "value" : "my value"}]}] } in collection: myCollection

But the result is like without using the custom converter, without the "_class" attribute :

{
    myClasses : [
        {
             "title" : "my title",
             "value" : "my value",
        }
    ]
}

My current conclusions are :

  • For inserting a new document, the custom converter works fine
  • For updating though, although the custom converter seems to be called (the debugging output is there), but it seems to be using
    the default MappingMongoConverter to do the real update.

Am i missing something ? Please share your thoughts ..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陈年往事 2025-01-01 21:32:42

看来当前版本(截至撰写本文时为 1.0 GA)并未将 Update 对象通过管道传输到 QueryMapper 中,后者负责将包含的潜在复杂对象按摩到MongoDB 可以本地处理处理。在此过程中,应调用 MongoConverter ,从而触发您的自定义转换器。

该问题已在您刚刚提交的票证中捕获,并将在下一个错误修复版本中修复(1.0.1、1.1.M1)。

It seems that the current version (1.0 GA as of the time of writing) does not pipe the Update object into the QueryMapper which is responsible to massage the contained potentially complex objects into ones MongoDB can handle handle natively. In that process the MongoConverter should be invoked which should in turn trigger your custom converters.

The issue is captured in the ticket you just filed and will be fixed with the next bugfix release (1.0.1, 1.1.M1).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文