AlanW
AlanW

Reputation: 71

How to retrieve a POJO from MongoDB via a Generic Class

I'm new to Mongo, and am trying to use it to implement a cache internally in our application. We have a defined cache interface (public Cache(K, V) ) with several alternative implementations (HashTable, JCS etc). I need to create a MongoDB implementation for some hard (i.e. expensive) to calculate data. The cache data will either be a POJO or a List of POJO's.

My problem is getting the Mongo response back into a POJO or (the bit that's eluded me so far), into a List of POJOs.

Code so far:

public class MongoDBCache<K, V> implements Cache<K, V>
{

private String name = null;

public MongoDBCache(String name)
{
    this.name = name;
}

public V get(K key)
{
    V result = null;
    try
    {

            DB mdb = getMongoDB();

            DBCollection mcol = mdb.getCollection(name);

            BasicDBObject query = new BasicDBObject("_id", key.toString());
            DBCursor cursor = mcol.find(query);

            if (cursor.hasNext())
            {
                Gson gson = new Gson();
                DBObject dbobj = cursor.next();

                Class type = ????;

                result = (V) gson.fromJson(dbobj.get("obj").toString(), type);

            }


    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    return result;
}
}

I can kind of make this work if the value is just a POJO (can get the type on the put method, not ideal but works), but I can't figure out how to make it work for a List. As an example, a ArrayList<Long> ends up as ArrayList<Double>.

Any suggestions? Something I can do in GSON? Something I can do with reflection? (I'm not tied into GSON, or any other library, this is just my current attempt).

Thanks, Alan

Upvotes: 3

Views: 2139

Answers (1)

giampaolo
giampaolo

Reputation: 6934

If you could save also your class type into the database along with the object, you could infer the right class using something like:

 if (cursor.hasNext())
        {
            Gson gson = new Gson();
            DBObject dbobj = cursor.next();

            Class type = Class.forName(dbobj.get("class").toString());

            result = (V) gson.fromJson(dbobj.get("obj").toString(), type);

        }

you can get the proper string with code like this:

SomeClass object = ...
Class c = object.getClass();
String cn = c.toString();

Edit

Pay attention that when you want to store on database the class type and you are dealing with generics, due to type erasure, you cannot do something like this:

ArrayList<Long> l = new ArrayList<Long>();  
String clazz = l.getClass

since clazz will store:

java.util.ArrayList

instead you need to do something like this

Type listType = new TypeToken<ArrayList<Long>>() {}.getType();
String clazz = l.getClass();

that will return you:

java.util.ArrayList<java.lang.Long>

Upvotes: 1

Related Questions