我在这里有一个非常奇怪的问题,我在列表内的对象内部迭代迭代的问题,并且有一个条件,问题是第二次迭代有条件设置值但是它适用于所有项目甚至如果条件是假的。
我有以下课程:
EventFeedKey(用作hashmap的键):
public class EventFeedKey {
private final int eventId;
private final int triggerId;
public EventFeedKey(int eventId, int triggerId) {
this.eventId = eventId;
this.triggerId = triggerId;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof EventFeedKey)) {
return false;
}
EventFeedKey otherKey = (EventFeedKey) object;
return this.eventId == otherKey.eventId && this.triggerId == otherKey.triggerId;
}
@Override
public int hashCode() {
int result = 17; // any prime number
result = 31 * result + Integer.valueOf(this.eventId).hashCode();
result = 31 * result + Integer.valueOf(this.triggerId).hashCode();
return result;
}
}
事件:
@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
}
EventType:
@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
}
EventTypeTrigger:
@Entity
@Table(name = "event_type_triggers")
public class EventTypeTrigger {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(nullable = false)
private String title;
@Transient
private int count;
// 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;
}
在getTriggersWithCounts()
内:
public HashMap<EventFeedKey, Integer> getTriggersWithCounts() {
HashMap<EventFeedKey, Integer> eventTriggers = new HashMap<>();
// event id : 1, trigger id 7
eventTriggers.put(new EventFeedKey(1,7), 5);
return eventTriggers;
}
Lets说我有以下数据:
代表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
的事件?
修改: 我认为现在的问题与我在Playframework中使用的Ebean http://ebean-orm.github.io/有关。
答案 0 :(得分:0)
首先,感谢@ArturBiesiadowski提示,问题只是来自Ebean引用实体实例,因为它们具有相同的@Id
,所以即使我为1个实体设置了值,但是当我得到实体时我得到了相同的实例,即使我没有坚持那个实体,并且在我检索列表之前它们是不同的,但是当我在修改后得到列表时,Ebean似乎得到了带有getter的修改后的实例。
解决方案只是使用其他对象(如DTO),我之前已经拥有它们,但是我修改了列表然后返回DTO,我做了什么我将列表转换为DTO然后修改了列表,这使它有效。
我使用http://mapstruct.org/在实体和DTO之间进行映射,我的DTO类与实体类相同但没有注释。
EventDTO:
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
}
EventTypeTriggerDTO:
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;
}
当然你需要去Mappers的MapStruct文档,但是如果你不想使用maplayer的mapper,那么想法只是将实体类映射到DTO类,使用你想要的任何Mapper,但是我是什么&#39 ;我确定MapStruct在这种情况下运行良好。