Issue
I have the following entity:
public class EventCategoryEntity {
private UUID id;
@Column("category_name")
private String categoryName;
@Column("group_name")
private String groupName;
}
Which I retrieve via Flux(one to many relationship):
public Flux<EventCategoryEntity> findAllCategories() {
return eventRepository.findAll();
}
@Query("select ec.id, ec.name as category_name,ecg.name as group_name" +
"from event_category ec left join event_category_relation ecr on (ec.id = ecr.event_category_id) " +
"left join event_category_group ecg on (ecr.event_category_group_id = ecg.id);")
Flux<EventCategoryEntity> findAll();
Then output via Controller in JSON response like:
{
"id": "87108493-4fc1-4b12-8ffc-e10aa039fc39",
"categoryName": "soccer",
"groupName": "team",
},
{
"id": "87108493-4fc1-4b12-8ffc-e10aa039fc39",
"categoryName": "soccer",
"groupName": "ball",
}
]
But I would like to aggregate response by id like this:
[
{
"id": "87108493-4fc1-4b12-8ffc-e10aa039fc39",
"categoryName": "soccer",
"groupName: ["team", "ball"]
}
]
I've prepared DTO object, but I don't know how this flux map into the this:
public class EventCategory {
private UUID id;
private String categoryName;
private List<CategoryGroup> categoryGroup;
private class CategoryGroup {
private String groupName;
}
}
Solution
You can use collectMultimap
which collects all elements emitted by this Flux into a Map.
@Test
public void collectMultimap() {
Flux<EventCategoryEntity> flux1 = Flux.just(
new EventCategoryEntity("87108493-4fc1-4b12-8ffc-e10aa039fc39","soccer","team"),
new EventCategoryEntity("87108493-4fc1-4b12-8ffc-e10aa039fc39","soccer","ball"),
new EventCategoryEntity("57108499-4fc1-4b52-8ffc-e11aa039fc85","soccer","tennis")
);
flux1.collectMultimap(EventCategoryEntity::getId, EventCategoryEntity::getGroupName)
.map(ids -> ids.keySet().stream().map(t -> {
List<String> categoryGroupList = ids.get(t).stream().toList();
Optional<EventCategoryEntity> f = flux1.toStream().filter(pp -> pp.getId().equals(t)).findFirst();
return new EventCategoryDTO(f.get().getId(), f.get().getCategoryName(), categoryGroupList);
}).toList())
.subscribe(result -> System.out.println(result.toString()));
}
Output:
[EventCategoryDTO(id=87108493-4fc1-4b12-8ffc-e10aa039fc39, categoryName=soccer, categoryGroup=[team, ball]), EventCategoryDTO(id=57108499-4fc1-4b52-8ffc-e11aa039fc85, categoryName=soccer, categoryGroup=[tennis])]
Answered By - anicetkeric
Answer Checked By - Cary Denson (JavaFixing Admin)