Java 为每个应用于所有项目而不是仅1的项目设置包含条件的值
我这里有一个非常奇怪的问题,我在列表中的对象中对列表进行迭代,这是一个条件,问题是第二次迭代有条件设置值,但它应用于所有项目,即使条件为false 我有以下课程: EventFeedKey(用作hashmap的键): 活动: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
@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;
}