Reputation: 71
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
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