Reputation: 337
I have a model classes like
public class MyClass extends ReflectionDBObject {
private List<NiceAttribute> attributes;
...
}
public class NiceAttribute extends ReflectionDBObject {
...
}
I create it in a typesafe way, like
List<NiceAttribute> attrs = new ArrayList<NiceAttribute>();
attrs.add(new NiceAttribute());
MyClass myClass = new MyClass();
myClass.setAttributes(attrs);
then save it to mongo, and retrieve with a code like
DBCollection col = ...;
col.setObjectClass(MyClass.class)
MyClass foundObject = (MyClass)col.findOne();
But the problem is that foundObject
's attributes
becomes a list of BasicDBObject
. Looks like a driver can not (or does not want to) detect a list items type. Is this a driver limitation, or I missed something? What would be an elegant workaround for the problem?
BTW, I know about Morphia etc. Maybe it solves the problem. But my project is tiny, and I don't want to complicate things having one more layer of abstraction.
Upvotes: 5
Views: 1144
Reputation: 15219
Well, there is a solution, but you're not gonna like it. Basically you can specify the corresponding class for an internal path within your object. Here's what I did, and it works:
public class Release extends ReflectionDBObject {
//other fields omitted
private List<ReleaseDetailsByTerritory> releaseDetailsByTerritory = new ArrayList<ReleaseDetailsByTerritory>();
}
public class ReleaseDetailsByTerritory extends ReflectionDBObject { //...}
Now, if I simply do this:
releaseColl.setObjectClass(Release.class);
releaseColl.setInternalClass("ReleaseDetailsByTerritory.0", ReleaseDetailsByTerritory.class);
Release r = (Release) releaseColl.findOne();
//the internal list will contain ReleaseDetailsByTerritory type objects (not DBObjects)
System.out.println(r.getReleaseDetailsByTerritory().get(0).getClass().getName());
The crappy thing here is that you can't (or at least I haven't found how) to specify the mapping class for ALL the elements of an embedded array. You CANNOT do something like:
releaseColl.setInternalClass("ReleaseDetailsByTerritory", ReleaseDetailsByTerritory.class);
or
releaseColl.setInternalClass("ReleaseDetailsByTerritory.*", ReleaseDetailsByTerritory.class);
You have instead to specify the mapping class of any possible element of the embedded array:
releaseColl.setInternalClass("ReleaseDetailsByTerritory.0", ReleaseDetailsByTerritory.class);
releaseColl.setInternalClass("ReleaseDetailsByTerritory.1", ReleaseDetailsByTerritory.class);
releaseColl.setInternalClass("ReleaseDetailsByTerritory.2", ReleaseDetailsByTerritory.class);
Upvotes: 4
Reputation: 7590
You should use Morphia. It adds support for POJOs and embedded objects (and collections). It doesn't have any of the limitations the driver does about requiring your classes to look like a Map<String, Object>
.
Upvotes: -1