spring-data-mongodb
spring-data-mongodb copied to clipboard
if there is no data "getUniqueMappedResult" throws an exception
Hello,
If you add a new function with Optional value return its would be useful to control return value.
Current Implementation and throw an exception if there is no data
@Nullable
public T getUniqueMappedResult() {
Assert.isTrue(mappedResults.size() < 2, "Expected unique result or null, but got more than one!");
return mappedResults.size() == 1 ? mappedResults.get(0) : null;
}
Optional<T> .....
Thanks
Please spend a bit more time describing your request (maybe outline the usage scenario you have in mind). Right now, we struggle to understand what you want to achieve.
Hi, Ok. I try to explain on my case and solution.
public StudentAttendanceDTO getAttendance(StudentAttendanceSearchDTO dto)
{
final List<AggregationOperation> pipeline =new ArrayList<>();
pipeline.add(Aggregation.group("info.studentId").count().as("courseEventsPlanned")
.sum(ConditionalOperators.Cond.when(Criteria.where("info.type").is(AttendanceType.PRESENT)).then(1).otherwise(0))
.as("courseEventsAttended")
..................
...................................
final AggregationResults<R> aggregate = template.aggregate(pipeline, collectionName, outputClass);
return uniqueResult(collectionName, AttendanceDTO.class,
Aggregation.newAggregation(pipeline));
}
// I have to use this method to return without exception. This my solution
private <R> R getUniqueResult(final AggregationResults<R> aggregate)
{
List<R> results = aggregate.getMappedResults();
if (isNotEmpty(results))
{
return results.get(0);
} else
{
return null;
}
}
// If I need optional version I use this
protected <R> Optional<R> getUniqueResultOf(final AggregationResults<R> aggregate)
{
List<R> results = aggregate.getMappedResults();
if (isNotEmpty(results))
{
return Optional.of(results.get(0));
} else
{
return Optional.empty();
}
}
instead of this implementation
public Optional<StudentAttendanceDTO> getAttendance(StudentAttendanceSearchDTO dto)
{
final List<AggregationOperation> pipeline =new ArrayList<>();
pipeline.add(Aggregation.group("info.studentId").count().as("courseEventsPlanned")
.sum(ConditionalOperators.Cond.when(Criteria.where("info.type").is(AttendanceType.PRESENT)).then(1).otherwise(0))
.as("courseEventsAttended")
..................
...................................
final AggregationResults<R> aggregate = template.aggregate(pipeline, collectionName, outputClass);
// It throws an exception if there is no data
return aggregate.getUniqueMappedResult();
// It would be very useful if you add to new version of this method like this
return aggregate.getUniqueMappedResultOf(); // optional and return object as Optional<StudentAttendanceDTO>
}
Sorry for long silence. We've been revisiting the issue and will not add an additional method returning Optional<T> to AggregationResults.
Optional.ofNullable(result.getUniqueMappedResult()) should be sufficient to support the described use case.