Skip to content

Instantly share code, notes, and snippets.

@delphym
Last active May 9, 2023 03:43
Show Gist options
  • Save delphym/964ff71de08197e7c384eaac2e353850 to your computer and use it in GitHub Desktop.
Save delphym/964ff71de08197e7c384eaac2e353850 to your computer and use it in GitHub Desktop.
Lambda Expressions with Streams magics
@Component
@Scope("prototype")
public class RequestHandler extends BaseRequestHandler<List<PositionEstablishment>> {
@Autowired
private PositionEstablishmentRepository positionEstablishmentRepository;
Date asAtDate;
private List<com.jemini.base.model.position.PositionEstablishment> establishments = new ArrayList<>();
private List<PositionDateEffective> positionDateEffectives;
public Date getAsAtDate() {return asAtDate;}
public void setAsAtDate(Date asAtDate) {this.asAtDate = asAtDate;}
@Override
public boolean validateRequest() throws RequestHandlingException {
positionDateEffectives = positionEstablishmentRepository.findAllAsAtDate(asAtDate);
if (positionDateEffectives == null) {
ResourceNotFoundException resourceNotFoundException = new ResourceNotFoundException(getWsErrorBy(WsErrorEnum.POSITION_ESTABLISHMENT_NOT_FOUND, String.valueOf(asAtDate)));
throw resourceNotFoundException;
}
return !hasValidationErrors();
}
@Override
protected List<PositionEstablishment> handleRequest() throws RequestHandlingException {
//Convert results (List of `PositionDateEffective`) from DB to the type the `@GET` method operates on (`PositionEstablishment` Entity from jemini.base)
establishments = positionDateEffectives.stream()
.map(PositionDateEffective::getPositionEstablishment)
.collect(Collectors.toList());
//Group those `PositionEstablishment` by their `externalID`
Map<String, List<com.jemini.base.model.position.PositionEstablishment>> establishmentsByExternalId =
establishments.stream()
.collect(Collectors.groupingBy(PositionEstablishmentEnt::getExternalId));
//To avoid getting "IncorrectResultSizeDataAccessException: result returns more than one elements;"
//(If such `externalId` was passed to single `@GET` method it will blow up exactly on this too.)
//We need to select entries with just one element in them.
Set<Map.Entry<String, List<PositionEstablishmentEnt>>> cleanEstablishmentsByExternalId =
establishmentsByExternalId.entrySet().stream()
.filter(entry -> entry.getValue().size() == 1)
.collect(Collectors.toSet());
//Create a list of individual `PositionEstablishment` (which is otherwise handled by single `@GET` method)
//And return it in the results list
List<PositionEstablishment> results = new ArrayList<>();
cleanEstablishmentsByExternalId.forEach(entry -> {
PositionEstablishment result = new PositionEstablishment();
result.setExternalId(entry.getKey());
result.setDatedPositionEstablishments(
entry.getValue().get(0).getPositionDateEffectiveRecords().stream().map(this::buildDatedPositionEstablishment).collect(Collectors.toList())
);
results.add(result);}
);
//Make sure we return everytime the same results, as the list is build by Streams in nondeterministic order
results.sort((p1, p2) -> p1.getExternalId().compareTo(p2.getExternalId()));
return results;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment