Java 为每个应用于所有项目而不是仅1的项目设置包含条件的值

Java 为每个应用于所有项目而不是仅1的项目设置包含条件的值,java,for-loop,playframework,ebean,Java,For Loop,Playframework,Ebean,我这里有一个非常奇怪的问题,我在列表中的对象中对列表进行迭代,这是一个条件,问题是第二次迭代有条件设置值,但它应用于所有项目,即使条件为false 我有以下课程: EventFeedKey(用作hashmap的键): 活动: @Entity @Table(name = "events") public class Event { @Id @Column @GeneratedValue(strategy = GenerationType.AUTO) private

我这里有一个非常奇怪的问题,我在列表中的对象中对列表进行迭代,这是一个条件,问题是第二次迭代有条件设置值,但它应用于所有项目,即使条件为false

我有以下课程:

EventFeedKey(用作hashmap的键):

活动:

@Entity
@Table(name = "events")
public class Event {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(nullable = false)
    private String title;

    @ManyToOne(optional = false)
    @JoinColumn(name = "type_id")
    private EventType type;

// Setters and Getters
}
事件类型:

@Entity
@Table(name = "event_types")
public class EventType {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(nullable = false)
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "eventType", cascade = CascadeType.ALL)
    @JsonManagedReference  
    private List<EventTypeTrigger> triggers = new ArrayList<>();

// Setters and Getters
}
下面的命令必须返回列表和触发器,其中包含
triggersFeed
中的计数值

    List<Event> eventList = new ArrayList<Event>();
    if (eventList != null) {
        HashMap<EventFeedKey, Integer> triggersFeed = getTriggersWithCounts();
        eventList.stream().forEach(event -> {
            event.getType().getTriggers().stream().forEach(eventTypeTrigger -> {
                EventFeedKey key = new EventFeedKey(event.getId(), eventTypeTrigger.getId());
                eventTypeTrigger.setCount(triggersFeed.get(key) != null ? (Integer) triggersFeed.get(key) : 0);
            });
        });
        return eventList;
    }
假设我有以下数据:

对于
事件列表

[  
   {  "id":1, "title":"Team A vs Team X", 
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":0
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
      {  
      "id":2, "title":"Team A vs Team C",
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":0
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
]
我从该方法得到的结果(这是错误的)是:

[  
   {  "id":1, "title":"Team A vs Team X", 
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":5
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
      {  
      "id":2, "title":"Team A vs Team C",
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":5
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
]
最烦人的是,如果我加上:

if (triggersFeed.get(key) != null) {
    System.out.print(triggersFeed.get(key).toString());
}
它将只打印一个结果

所以问题是:为什么修改id为2的事件

编辑
我认为现在的问题与Ebean有关:我在Playframework中使用了它。

首先,感谢@ArturBiesiadowski的提示,问题只是来自引用实体实例的Ebean,因为它们具有相同的
@Id
,所以即使我为1个实体设置了值,但当我得到实体时,我得到了相同的实例,即使我没有持久化那个实体,它们在我检索列表之前是不同的,但是当我在修改列表之后返回列表时,似乎可以使用getter获取修改后的实体

解决方案就是简单地使用另一个对象(比如DTO),我以前已经有了它们,但是我修改了列表,然后返回DTO,我所做的是将列表转换为DTO,然后修改了列表,这使它能够工作

我使用的是实体和DTO之间的映射,我的DTO类与实体类相同,但没有注释

事件收件人:

public class EventDTO {
    private Integer id;
    private String title;
    private EventTypeDTO type;

// Setters and Getters
}
EventTypeDTO:

public class EventTypeDTO {
    private Integer id;
    private String title;
    private List<EventTypeTriggerDTO> triggers = new ArrayList<>();

// Setters and Getters
}
现在的代码是:

    List<Event> eventList = new ArrayList<Event>();

    if (eventList != null) {
        List<EventDTO> eventDTOList = new ArrayList<>(EventMapper.INSTANCE.map(eventList));
        HashMap<EventFeedKey, Integer> triggersFeed = getTriggersWithCounts();
        eventList.stream().forEach(event -> {
            event.getType().getTriggers().stream().forEach(eventTypeTrigger -> {
                EventFeedKey key = new EventFeedKey(event.getId(), eventTypeTrigger.getId());
                eventTypeTrigger.setCount(triggersFeed.get(key) != null ? (Integer) triggersFeed.get(key) : 0);
            });
        });
        return eventDTOList;
    }
List eventList=new ArrayList();
if(eventList!=null){
List eventDTOList=newarraylist(EventMapper.INSTANCE.map(eventList));
HashMap triggersFeed=getTriggersWithCounts();
eventList.stream().forEach(事件->{
event.getType().getTriggers().stream().forEach(eventTypeTrigger->{
EventFeedKey=newEventFeedKey(event.getId(),eventTypeTrigger.getId());
eventTypeTrigger.setCount(triggersFeed.get(键)!=null?(整数)triggersFeed.get(键):0);
});
});
返回事件列表;
}

当然,您需要访问MapStruct文档以了解映射程序,但是如果您不想使用MapStruct的Mapper,那么您的想法只是将实体类映射到DTO类,可以使用您想要的任何映射程序,但我确信MapStruct在这种情况下运行良好。

您是如何构建数据的?我的感觉是,在两个事件实例中都有指向相同EventType的指针,当您从一个事件更新它时,它就是另一个事件中存在的相同对象Event@ArturBiesiadowski这些是我从数据库中获取的实体,我有另一个列表,但在1级(不是嵌套循环)中没有这样的问题。我考虑过指针,但在调试中我看不到这一点。我执行了您提供的示例(手动构造每个输入事件),输出完全符合预期(仅修改了事件id=1的EventTypeTrigger id=7)。几乎可以肯定的是,在两个事件中使用相同的EventTypeTrigger对象时会出现问题。嗯,调试对象中的问题看起来非常不同,甚至毫无意义,因为存在实体,我正在使用play frameworkebean@ArturBiesiadowski谢谢,我有主意了,您所说的提示让我关注ebean框架,这就是问题所在,ebean引用了相同的实体实例,因为它们具有相同的“id”,我不确定这是否是一个bug,但这就是问题所在。
public class EventDTO {
    private Integer id;
    private String title;
    private EventTypeDTO type;

// Setters and Getters
}
public class EventTypeDTO {
    private Integer id;
    private String title;
    private List<EventTypeTriggerDTO> triggers = new ArrayList<>();

// Setters and Getters
}
public class EventTypeTriggerDTO  {
    private Integer id;
    private String title;
    private int count;

// Setters and Getters
}
    List<Event> eventList = new ArrayList<Event>();

    if (eventList != null) {
        List<EventDTO> eventDTOList = new ArrayList<>(EventMapper.INSTANCE.map(eventList));
        HashMap<EventFeedKey, Integer> triggersFeed = getTriggersWithCounts();
        eventList.stream().forEach(event -> {
            event.getType().getTriggers().stream().forEach(eventTypeTrigger -> {
                EventFeedKey key = new EventFeedKey(event.getId(), eventTypeTrigger.getId());
                eventTypeTrigger.setCount(triggersFeed.get(key) != null ? (Integer) triggersFeed.get(key) : 0);
            });
        });
        return eventDTOList;
    }