2012-09-10 27 views
5

Chciałbym być w stanie przetrwać i odzyskać, między innymi, mapę map w kolekcji MongoDB. Używam Java, aby uzyskać dostęp do MongoDB przez Morphia.Trwałość i odzyskiwanie mapy map za pomocą Morphia i Mongodb

Przykład, którego używam poniżej, to zbiór zawierający dokumenty szczegółowo przedstawiające właścicieli różnych samochodów. W tym przykładzie liczba pojazdów konkretnej marki i modelu jest przechowywana na mapie map.

Większość właściwości działa bez żadnych problemów, ale w przypadku, gdy właściwość jest mapą zdefiniowaną na mapie w następujący sposób:

@Property("vehicles") 
private Map<String, Map<String, Integer> vehicles = new HashMap<String, HashMap<String, Integer>>(); 

utworzeniu obiektu (niektóre wartości włożona mapie) i utrzymywał się do bazy danych Mongo, jak można by oczekiwać, że będzie:

"vehicles" : { 
    "FORD" : { 
     "FIESTA" : 1 
    }, 
    "TOYOTA" : { 
     "COROLLA" : 1,     
     "PRIUS": 1 
    }, 
    "BMW" : { 
     "SLK" : 1 
    } 
} 

jednak gdy obiekt jest pobierane za pośrednictwem kodu java (zapytanie w MongoDB co nsole działa zgodnie z oczekiwaniami)) w następujący sposób ...

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

... kod ginie w okropny sposób na q.fetch() online.

Proszę o pomoc :)

Odpowiedz

7

Problem wynika z faktu, że mapa (jest interfejs) nie ma domyślnego konstruktora, a jednocześnie morfiny został poprawnie przypisywania konstruktora dla konkretnej HashMap na zewnętrznej nim mapą nie udało się rozwiązać konstruktora dla wewnętrznej mapy. Powodowało to wyjątek NullPointerException.

Po wielu debugowaniu i wypróbowaniu tego i owego, w końcu natknąłem się (z pomocą kolegi) na rozwiązanie.

  • Zamiast korzystać z adnotacji @Property użyj @Embedded. i
  • stwierdzenie mapy za pomocą betonu HashMap i nie korzystać z interfejsu Mapa

    @Embedded("vehicles") 
    private HashMap<String, HashMap<String, Integer>> vehicles = new HashMap<String, HashMap<String, Integer>>(); 
    

Dla tych z Was, którzy zastanawiają się ... określający konkretną klasę zarówno w @Property lub @Embedded Adnotacja nie zrobiła nic, aby pomóc w rozwiązaniu konstruktora dla wewnętrznej mapy HashMap.

2

Ponieważ używaliśmy nasz własny typ danych w ten sposób

private HashMap<String, HashMap<String, OwnDataType>> vehicles = new HashMap<String, HashMap<String, OwnDataType>>(); 

wszystkie wcześniejsze zalecenia nie działa; jedyną rzeczą co morfina odczytu danych odpowiednio było przekształcenie OwnDataType do formy liczby mnogiej, która jest utrzymywanie mapę wewnątrz samego OwnDataType a nie za pomocą map wewnątrz map:

private HashMap<String, OwnDataTypes> vehicles = new HashMap<String, OwnDataTypes>(); 

porządku Teraz wszystko działa.