将多个对象合并为Morphia的复杂对象时出现问题

时间:2012-01-26 13:45:32

标签: java collections concurrency 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
}

我的目标是使用Morphia在MongoDB中保存Person对象,这就是我希望我的文档布局的方式。我已经创建了一个文档构建器,它组合了每个对象的列表。每个人都会获得所有活动的列表,但只能收到特定的礼物。虽然我的文档构建器确实创建了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)
   }
}

如果我稍微修改代码以通过删除外部循环并让方法为Persons列表的特定索引获取参数来一次处理一个人:

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

我用正确的礼物得到一个完整的Person对象。如果尝试将此修改版本提供给循环,问题就会出现。我尝试过使用常规for循环和同步集合。我已经尝试过使用Google Guava的ImmutableArrayList但仍然没有运气。我知道问题是我在访问它们时正在更改列表但我无论如何都找不到它。我编写了一个直接使用MongoDB驱动程序的DAO,它运行正常,但代码更多,而且非常难看。我真的希望这种方法起作用,答案就在我的面前,但我却看不到它。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

这是你的问题:

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

您只为一个人添加礼物;如果您想将所有礼物聚合到活动中,请重新使用现有列表。

答案 1 :(得分:0)

我对MongoDB或Morphia一无所知,但我怀疑问题在于你使用了setter event.setGifts(somePersonsGifts)person.setEvents(events)。您的代码似乎没有将现有的礼物和事件列表与您在循环中进一步计算的礼物和事件列表合并,这就是您希望它的行为方式(如果我正确理解了问题)。 您应该检索已经存在的礼物列表(以及事件列表),而不是用空的新礼物列表覆盖它们。

答案 2 :(得分:0)

我不知道方法merge()是否在列表中,但我认为因为你在这里使用列表事件

person.setEvents(events);

也许你的意思

person.setEvents(listOfEvents)

请注意,您要将所有事件添加到每个人。如果所有人都去参加了所有活动,就没有必要在这个活动中进行活动。