19

MongoDB seems to return BSON/JSON objects.

I thought that surely you'd be able to retrieve values as Strings, ints etc. which can then be saved as POJO.

I have a DBObject (instantiated as a BasicDBObject) as a result of iterating over a list ... (cur.next()).

Is the only way (other than using some sort of persistence framework) to get the data into a POJO to use a JSON serlialiser/deserialiser?

My method looks like this:

public List<User> findByEmail(String email){
         DBCollection userColl;
         try {
            userColl = Dao.getDB().getCollection("users"); } catch (UnknownHostException e) { e.printStackTrace(); } catch (MongoException e) { e.printStackTrace();}
            DBCursor cur = userColl.find();
            List<User> usersWithMatchEmail = new ArrayList<User>();

            while(cur.hasNext()) {
               // this is where I want to convert cur.next() into a <User> POJO
               usersWithMatchEmail.add(cur.next());
            }
        return null;
    }

EDIT: It's pretty obvious, just do something like this.

2
  • 1
    Stupid me, you can just call get(<key>) on a DBObject and get the value. I'll post the code. Commented Oct 7, 2011 at 7:39
  • I just want to point out the most recent answer, where a driver-native solution is proposed: stackoverflow.com/a/49926224/503900 Commented Apr 22, 2018 at 10:14

5 Answers 5

49

Let Spring do the heavy lifting with the stuff it already has built for this...

The real trick is: mongoTemplate.getConverter().read(Foo.class, obj);

For example, when using a DBCursor -

while (cursor.hasNext()) { 
    DBObject obj = cursor.next(); 
    Foo foo = mongoTemplate.getConverter().read(Foo.class, obj);  
    returnList.add(foo); 
}

http://revelfire.com/spring-data-mongodb-convert-from-raw-query-dbobject/

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for this. For a quick start, the maven dependency is: org.springframework.data / spring-data-mongodb / 1.3.2.RELEASE
You deserve a cookie :D
nice work chris mathias. But i also need reverse of this process. i.e converting java object to BasicDbObject. any help? Thanks
The question was not about SPRING
8

There is a few java libs that can help you with it:

3 Comments

Thanks, for now I'm trying to learn the Java API but will use one of those eventually.
+1 for spring-data-mongodb, its fantastic. Has annotations to specify document ID, field names, doc references; be aware there is no support for cascading saves: static.springsource.org/spring-data/data-mongodb/docs/current/…
@AndrewB can Spring data mongodb be used in an EJB project? And is it a wise thing to do? Since rest of my project has no dependency over Spring whatsoever!
6

Though a late answer , someone might find this useful.

I use GSON to convert from BasicDBObject to my own POJO which is TinyBlogDBObject

TinyBlogDBObject obj = convertJSONToPojo(cursor.next().toString());

private static TinyBlogDBObject convertJSONToPojo(String json){

    Type type = new TypeToken< TinyBlogDBObject >(){}.getType();

    return new Gson().fromJson(json, type);

}

2 Comments

this doesn't work because of the id returned in the form {"_id":{"$oid":xxxx} and gson complains. You need to manually convert it to a string or replace the value in a jsonobject.
Or you can supply your own _id values as strings in the first place, and avoid problems like that.
5

1. Provide MongoDatabase bean with proper CodecRegistry

@Bean
public MongoClient mongoClient() {
    ConnectionString connectionString = new ConnectionString("mongodb://username:[email protected]:27017/dbname");

    ConnectionPoolSettings connectionPoolSettings = ConnectionPoolSettings.builder()
            .minSize(2)
            .maxSize(20)
            .maxWaitQueueSize(100)
            .maxConnectionIdleTime(60, TimeUnit.SECONDS)
            .maxConnectionLifeTime(300, TimeUnit.SECONDS)
            .build();

    SocketSettings socketSettings = SocketSettings.builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .build();

    MongoClientSettings clientSettings = MongoClientSettings.builder()
            .applyConnectionString(connectionString)
            .applyToConnectionPoolSettings(builder -> builder.applySettings(connectionPoolSettings))
            .applyToSocketSettings(builder -> builder.applySettings(socketSettings))
            .build();

    return MongoClients.create(clientSettings);
}

@Bean 
public MongoDatabase mongoDatabase(MongoClient mongoClient) {
    CodecRegistry defaultCodecRegistry = MongoClientSettings.getDefaultCodecRegistry();
    CodecRegistry fromProvider = CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build());
    CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(defaultCodecRegistry, fromProvider);
    return mongoClient.getDatabase("dbname").withCodecRegistry(pojoCodecRegistry);
}

2. Annotate POJOS

public class ProductEntity {

    @BsonProperty("name") public final String name;
    @BsonProperty("description") public final String description;
    @BsonProperty("thumb") public final ThumbEntity thumbEntity;

    @BsonCreator
    public ProductEntity(
            @BsonProperty("name") String name,
            @BsonProperty("description") String description,
            @BsonProperty("thumb") ThumbEntity thumbEntity) {
        this.name = name;
        this.description = description;
        this.thumbEntity = thumbEntity;
    }
}

public class ThumbEntity {

    @BsonProperty("width") public final Integer width;
    @BsonProperty("height") public final Integer height;
    @BsonProperty("url") public final String url;

    @BsonCreator
    public ThumbEntity(
            @BsonProperty("width") Integer width,
            @BsonProperty("height") Integer height,
            @BsonProperty("url") String url) {
        this.width = width;
        this.height = height;
        this.url = url;
    }
}

3. Query mongoDB and obtain POJOS

MongoCollection<Document> collection = mongoDatabase.getCollection("product");
Document query = new Document();
List<ProductEntity> products = collection.find(query, ProductEntity.class).into(new ArrayList<>());

Please check my answer in other post
POJO to org.bson.Document and Vice Versa

2 Comments

How do you handle date/time classes in case of using POJOs?
You do not have to use date/time mongo data type at all. Instead you can use long datatype where you can save current timestamp. There is also second probably even better option that you can get a date from ObjectId. I always use one of these two options (long or object id), I never use date/time mongo data type
2

You can use GSON library provided by Google. Here is the example of it. There are many other api that you can use to convert json into pojo like jettision api,etc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.