Question

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 ..

Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top