I have an entity object with several columns which looks like this:
@Entity
@Table(name = "stats", schema = "main")
@Getter @Setter
@AllArgsConstructor @NoArgsConstructor
public class StatsEntity implements Serializable {
private static final long serialVersionUID = 743865321018464769L;
@EmbeddedId
private StatsEntityIds id;
@Column(length = 500, name = "total_count")
private Integer totalCount;
@Column(length = 500, name = "success")
private Integer success;
@Column(length = 500, name = "errors")
private Integer errors;
}
As I use a composite key I have an embeddable class
@Embeddable
@Getter @Setter
public class StatsEntityIds implements Serializable {
private static final long serialVersionUID = 743865321018464768L;
@Column(length = 255, name = "date")
private String date;
@Column(length = 100, name = "workflow")
private String workflow;
@Column(length = 100, name = "type")
private String type;
}
I also have a repository class and I use several request. The following query allow to select database results based on a query on workflow value.
@Repository
public interface StatsRepository extends JpaRepository<StatsEntity, StatsEntityIds> {
List<StatsEntity> findByIdWorkflowOrderByIdDate(String workflow);
}
String dates have the following format: 2022-04-05 (YYYY-MM-dd). My issue is the following. the query is working fine in my service layer and i do obtain the right outputs:
@Override
public List<StatsDto> findByIdWorkflowOrderByIdDate(DsiPilotStatisticsRequest request) {
ModelMapper modelMapper = mappingConfiguration();
List<StatsEntity> statEntities = this.statsRepository.findByIdWorkflowOrderByIdDate(request.getWorkflow());
return modelMapper.map(statEntities, new TypeToken<List<StatsDto>>(){}.getType());
}
Here is where i'm a little bit stuck. I want to operate a group by using stream. For example the previous query is returning 1000 results on 300 days. Let's consider I want to group them and do sums on numeric columns.
For grouping by full date, I implemented the following stream that return my DTO object and do make sums for each day.
return this.statsRepository.findByIdWorkflowOrderByIdDate(request.getWorkflow())
.parallelStream()
.map(statEntity -> new StatsDto(
statEntity.getId().getDate(),
statEntity.getId().getWorkflow(),
statEntity.getTotalCount(),
statEntity.getSuccess(),
statEntity.getErrors()))
.collect(Collectors.toMap(
StatsDto::getDate,
Function.identity(),
(val1, val2) -> new StatsDto(
val1.getDate(),
val1.getWorkflow(),
Integer.sum(val1.getTotalCount(), (val2.getTotalCount())),
Integer.sum(val1.getSuccess(), (val2.getSuccess())),
Integer.sum(val1.getErrors(), (val2.getErrors()))
)
))
.values()
.stream()
.sorted(Comparator.comparing(StatsDto::getDate))
.collect(Collectors.toList());
Now I would like to build a similar query that would sum my values based on week and month.