Is this a defect or feature or user error? Mapping to a map.

115 views
Skip to first unread message

John Ferguson

unread,
Apr 9, 2014, 9:20:21 AM4/9/14
to jongo...@googlegroups.com
I am interested in Jongo for its cleaner and more pleasant Query API for more advanced queries than what I show here. I am not using it as an ORM but rather a Map getter.  However, when I use it to do so it fails.  I am not sure if the failure is my doing, a feature or a bug.  Please let me know if I need to post an issue for a defect.

My POM includes:

       <dependency>
            <groupId>org.jongo</groupId>
            <artifactId>jongo</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>2.11.4</version>
        </dependency>

I am running:

Mongo 2.4.6

java version "1.7.0_51"
OpenJDK Runtime Environment (fedora-2.4.5.1.fc20-x86_64 u51-b31)
OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)


Plain old Mongo Sample

        DB db = new MongoClient("localhost").getDB("neuron");
        DBCollection collection = db.getCollection("test_data");

        DBObject findOne = collection.findOne();

        @SuppressWarnings("unchecked")
        Map<String, BSONObject> map = findOne.toMap();

        map.remove("_id");

        String json = new Gson().toJson(map);
        System.out.printf("A filtered map straight up from Mongo:  %s\n", json);

Works as desired, however I am not sure what I am doing incorrectly with Jongo because this analogous code fails:


    DB db = new MongoClient("localhost").getDB("neuron");
    Jongo jongo = new Jongo(db);
    MongoCollection test_data = jongo.getCollection("test_data");

    FindOne findOne = test_data.findOne();
    ResultHandler<Map> resultHandler = new ResultHandler<Map>() {

        @Override
        public Map map(DBObject dbObject) {
        // TODO Annoyance - Jongo somehow ends up with a dbObject
        // which is not able to got to a map.
        Map map = dbObject.toMap();

        map.remove("_id");
        return map;
        }

    };

    Map asMap = findOne.map(resultHandler);

    System.out.println("What do we have?");
    System.out.printf("For the record ---> %s\n", new Gson().toJson(asMap));


Fails with:

java.lang.UnsupportedOperationException: Not Supported
    at org.bson.LazyBSONObject.toMap(LazyBSONObject.java:402)
    at com.coldlight.neuron.db.JongoSpikeTest$1.map(JongoSpikeTest.java:49)
    at com.coldlight.neuron.db.JongoSpikeTest$1.map(JongoSpikeTest.java:1)
    at org.jongo.FindOne.map(FindOne.java:51)
    at com.coldlight.neuron.db.JongoSpikeTest.shouldBeAbleToMapToDataResultsForSingleRecord(JongoSpikeTest.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)



Benoît GUEROUT

unread,
Apr 9, 2014, 9:54:25 AM4/9/14
to jongo...@googlegroups.com
Hi, thanks for your feedback.

I don't know if java driver support toMap() calls on a LazyDBObject which is used by Jongo.

You can map your document to a Map object : 
Here is an example :

    @Test
    public void canFindAndSaveMap() throws Exception {

        collection.insert("{name:'John'}");
        Map<String, String> map = collection.findOne().as(Map.class);
        map.put("name", "Robert");

        collection.save(map);

        Map result = collection.findOne().as(Map.class);
        assertThat(result.get("name")).isEqualTo("Robert");
        assertThat(result.get("_id")).isNotNull();
    }



--
You received this message because you are subscribed to the Google Groups "Jongo" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jongo-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Benoît GUEROUT

unread,
Apr 9, 2014, 10:10:21 AM4/9/14
to jongo...@googlegroups.com
Ok so LazyDBObject does not support toMap() method : 

public class LazyDBObject extends LazyBSONObject implements DBObject {
..
public Map toMap(){
        throw new UnsupportedOperationException( "Not Supported" );
    }

Let me know if the previous solution meets your needs.
If not, i can make some test to convert the LazyDBObject to a BasicDBObject into a ResultHandler

John Ferguson

unread,
Apr 9, 2014, 10:25:18 AM4/9/14
to jongo...@googlegroups.com
Your solution  meets my current needs for findOne.  I will make sure that other usages (find with many) work out fine.  Also, I should have simply tried this myself - it is clearly documented.  I assume this "issue" may require at most a slight change to some documentation?  Again,  thanks for your quick reply.
Reply all
Reply to author
Forward
0 new messages