Как получить правильно типизированный список из ReflectionDBObject - PullRequest
5 голосов
/ 21 июля 2010

У меня есть модель классов, таких как

public class MyClass extends ReflectionDBObject {
    private List<NiceAttribute> attributes;    
    ...
}

public class NiceAttribute extends ReflectionDBObject {
    ...
}

Я создаю его безопасным способом, например

List<NiceAttribute> attrs = new ArrayList<NiceAttribute>();
attrs.add(new NiceAttribute());
MyClass myClass = new MyClass();
myClass.setAttributes(attrs);

затем сохраните его в mongo и получите с кодом, подобным

DBCollection col = ...;
col.setObjectClass(MyClass.class)
MyClass foundObject = (MyClass)col.findOne();

Но проблема в том, что foundObject attributes становится списком BasicDBObject. Похоже, драйвер не может (или не хочет) определять тип элементов списка. Это ограничение водителя или я что-то пропустил? Что было бы элегантным решением проблемы?

Кстати, я знаю о Морфии и т. Д. Возможно, это решает проблему. Но мой проект крошечный, и я не хочу усложнять вещи, имея еще один уровень абстракции.

Ответы [ 2 ]

4 голосов
/ 13 января 2012

Ну, есть решение, но оно тебе не понравится. По сути, вы можете указать соответствующий класс для внутреннего пути в вашем объекте. Вот что я сделал, и это работает:

public class Release extends ReflectionDBObject {

    //other fields omitted    

    private List<ReleaseDetailsByTerritory> releaseDetailsByTerritory = new ArrayList<ReleaseDetailsByTerritory>();

}

public class ReleaseDetailsByTerritory extends ReflectionDBObject { //...}

Теперь, если я просто сделаю это:

    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());

Дрянная вещь в том, что вы не можете (или, по крайней мере, я не нашел как) указать класс отображения для ВСЕХ элементов встроенного массива. Вы НЕ МОЖЕТЕ сделать что-то вроде:

releaseColl.setInternalClass("ReleaseDetailsByTerritory", ReleaseDetailsByTerritory.class);

или

releaseColl.setInternalClass("ReleaseDetailsByTerritory.*", ReleaseDetailsByTerritory.class);

Вместо этого вы должны указать класс отображения любого возможного элемента встроенного массива:

releaseColl.setInternalClass("ReleaseDetailsByTerritory.0", ReleaseDetailsByTerritory.class);
releaseColl.setInternalClass("ReleaseDetailsByTerritory.1", ReleaseDetailsByTerritory.class);
releaseColl.setInternalClass("ReleaseDetailsByTerritory.2", ReleaseDetailsByTerritory.class);
0 голосов
/ 08 августа 2010

Ты должен использовать Морфию. Добавлена ​​поддержка POJO и встроенных объектов (и коллекций). Он не имеет никаких ограничений, которые делает драйвер, заставляя ваши классы выглядеть как Map<String, Object>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...