Проблемы с объединением нескольких объектов в сложный объект для Morphia

Я пытаюсь объединить эти три объекта в один сложный объект:

public class Person {
   private String name;
   private List<Event> events;

   // getters and setters
}
public class Event {
   private String name;
   private List<Gift> gifts;

   // getters and setters
}
public class Gift {
   private String name;
   private String recipient;// the name of the person
   private String eventName;

  // getters and setters
}

Моя цель - сохранить объект Person в MongoDB с помощью Morphia, и именно так я хочу, чтобы мой документ был выложен. Я создал своего рода конструктор документов, который объединяет списки каждого объекта. Каждый Человек получает список всех Событий, но может получать только определенные Подарки. Хотя мой построитель документов создает документ, который Morphia может сохранять, в события для всех лиц вставляются только подарки последнего получателя (порядок сортировки). Хотя бы для правильных событий.

public void merge() {
   for (Person person : listOfPersons) {
      for (Event event : listOfEvents) {
         // somePersonsGifts: a sublist of gifts based on Event and Person.
         List<Gift> somePersonsGifts = new ArrayList<Gift>();               
         for (Gift gift : listOfGifts) {
            if (person.getName().equals(gift.getRecipient()) &&  gift.getEventName().equals(event.getName())) {
                  somePersonsGifts.add(gift);
            }
         }
         event.setGifts(somePersonsGifts);
      }
      person.setEvents(listOfEvents)
   }
}

Если я немного изменю код, чтобы обрабатывать одного человека за раз, удалив внешний цикл и заставив метод принимать аргумент для определенного индекса списка людей:

public void merge(int p) {
   Person person = listOfPersons.get(p);
   //...and so on

Я получаю один полный объект Person с правильными подарками. Если попытаться загрузить эту измененную версию в цикл, проблема вернется. Я пытался использовать обычные циклы for и синхронизированные коллекции. Я пытался использовать ImmutableArrayList от Google Guava, и все равно не повезло. Я знаю, что проблема в том, что я меняю списки при доступе к ним, но я все равно не могу их найти. Я написал DAO, который использует драйвер MongoDB напрямую, и он работает правильно, но это намного больше кода и довольно уродливо. Я действительно хочу, чтобы этот подход работал, ответ передо мной, но я просто не вижу его. Любая помощь будет принята с благодарностью.


person Francois Green    schedule 26.01.2012    source источник
comment
Вы не уточнили, в чем у вас проблема, вы только намекаете на это.   -  person Tassos Bassoukos    schedule 26.01.2012
comment
Я попытался повторно использовать тот же список, но проблема не исчезла. Прошу прощения за недостаточно ясность. Я не хочу добавлять все подарки всем людям, поэтому у меня есть условное выражение в самом внутреннем цикле. Я хочу добавить Подарки, соответствующие определенному имени и определенному событию. Я твердо верю, что такое поведение происходит из-за того, что я копирую не текущий список somePersonGifts, когда добавляю его в событие, а ссылку на него, поэтому последние значения в списке somePersonGifts — это значения, хранящиеся во всех копиях. Спасибо всем за их усилия от моего имени.   -  person Francois Green    schedule 28.01.2012


Ответы (3)


Вот ваша проблема:

List<Gift> somePersonsGifts = new ArrayList<Gift>();               
....
event.setGifts(somePersonsGifts);

Вы добавляете подарки только для одного человека; если вы хотите объединить все подарки в событие, повторно используйте существующий список.

person Tassos Bassoukos    schedule 26.01.2012

Я ничего не знаю о MongoDB или Morphia, но подозреваю, что проблема в том, что вы используете сеттеры event.setGifts(somePersonsGifts) и person.setEvents(events). Ваш код, похоже, не объединяет существующие списки подарков и событий с теми, которые вы рассчитываете дальше в цикле, а именно так, как вы хотели бы, чтобы он вел себя (если я правильно понимаю вопрос). Вы должны получить уже существующий список подарков (и список событий тоже) вместо того, чтобы перезаписывать их пустыми новыми.

person fredo    schedule 26.01.2012

Я не знаю, находится ли метод merge() внутри списка, но я предполагаю, что, поскольку вы используете здесь события списка

person.setEvents(events);

Возможно, вы имели в виду

person.setEvents(listOfEvents)

Обратите внимание, что вы добавляете все события для каждого человека. Если все люди побывали на всех событиях, нет необходимости иметь события внутри человека.

person toto_tico    schedule 26.01.2012