Сохранение и получение карты карт с морфием и Mongodb
Я хотел бы иметь возможность сохранять и извлекать, среди прочего, карту карт в коллекции MongoDB. Я использую Java для доступа к MongoDB через Morphia.
Пример, который я использую ниже, - это коллекция, содержащая документы, подробно описывающие владельцев различных автомобилей. В этом примере количество транспортных средств определенной марки и модели хранится на карте картБольшинство свойств работают без каких-либо проблем, но для случая, когда a свойство-это карта карты, определенная следующим образом:
@Property("vehicles")
private Map<String, Map<String, Integer> vehicles = new HashMap<String, HashMap<String, Integer>>();
Объект создается (некоторые значения вставляются в карту) и сохраняется в базе данных Mongo, как и следовало ожидать:
"vehicles" : {
"FORD" : {
"FIESTA" : 1
},
"TOYOTA" : {
"COROLLA" : 1,
"PRIUS": 1
},
"BMW" : {
"SLK" : 1
}
}
Однако, когда объект извлекается с помощью кода java (запрос на консоли MongoDB работает как ожидалось)) следующим образом...
Query<Owner> q = ds.find(Owner.class);
System.out.println(q.countAll());
Iterable<Owner> i = q.fetch();
for (Owner o : i) {
System.out.println(o);
}
...код умирает ужасным образом в строке q. fetch ().
Пожалуйста, помогите :)
2 ответа:
Проблема возникает из-за того, что карта (будучи интерфейсом) не имеет конструктора по умолчанию, и хотя Morphia правильно назначала конструктор для конкретной хэш-карты на внешней карте, она не смогла решить конструктор для внутренней карты. Это привело к NullPointerException.
После долгой отладки и пробования того и другого, в конце концов я наткнулся (с помощью коллеги) на решение.
- вместо использования свойства @ использование аннотации @встраиваемых. и
Объявляйте карты с помощью конкретной хэш-карты и не используйте интерфейс карты
@Embedded("vehicles") private HashMap<String, HashMap<String, Integer>> vehicles = new HashMap<String, HashMap<String, Integer>>();
Для тех из вас, кто интересуется... указание конкретного класса либо в свойстве@, либо в аннотации @Embedded никак не помогло разрешить конструктор для внутренней хэш-карты.
Поскольку мы использовали наш собственный тип данных таким образом
private HashMap<String, HashMap<String, OwnDataType>> vehicles = new HashMap<String, HashMap<String, OwnDataType>>();
Все предыдущие рекомендации не сработали; единственное, что заставило морфию правильно прочитать данные, - это преобразовать собственный тип во множественную форму, то есть сохранить карту внутри самого собственного типа и не использовать карты внутри карт:
private HashMap<String, OwnDataTypes> vehicles = new HashMap<String, OwnDataTypes>();
Теперь все работает нормально.