Last active
May 9, 2023 03:43
-
-
Save delphym/964ff71de08197e7c384eaac2e353850 to your computer and use it in GitHub Desktop.
Lambda Expressions with Streams magics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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