Use JDK 11.0.3. I have the following code snippet:
Set<String> allNumbersSet = customerInfoService.getCustomerPhoneNumbers(bankCustomerId);
additionalInformation
.map(info -> info.get(BANK_PE_CUSTOMER_ID_KEY))
.filter(StringUtils::isNotEmpty)
.ifPresent(id -> allNumbersSet.addAll(customerInfoService.getCustomerPhoneNumbers(id))); // fails here
Where get phone numbers is just Collectors.toSet():
@Override
public Set<String> getCustomerPhoneNumbers(String customerId) {
return backOfficeInfoClient.getCustByHashNo(customerId).getPropertyLOVs()
.flatMap(property -> property.getValues().values().stream())
.collect(Collectors.toSet());
}
However, it fails with:
java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.addAll(ImmutableCollections.java:76)
at service.impl.UserManagementServiceImpl.lambda$validateNewLogin$3(UserManagementServiceImpl.java:69)
If I update like the following:
var allNumbersSet = new HashSet<>(customerInfoService.getCustomerPhoneNumbers(bankCustomerId));
It works fine now.
What is wrong with the above code usage? Could you explain why this exactly appears?
This method call is surrounded by calling Hazelcast cache - before and after. As mentioned at comments it could be a reason for such behaviour:
The cached values are represented using immutable collections, which makes sense, as that allows sharing without the need for defensive copies
SOLUTION:
Found the way how to rewrite this logic and do that stuff without merging two sets:
var numbersSet = customerInfoService.getCustomerPhoneNumbers(id);
if (!numbersSet.contains(newLogin)) {
var peNumbersSet = additionalInformation
.map(info -> info.get(BANK_PE_CUSTOMER_ID_KEY))
.filter(StringUtils::isNotEmpty)
.map(customerInfoService::getCustomerPhoneNumbers)
.orElseGet(Collections::emptySet);
if (!peNumbersSet.contains(newLogin)) {
throw new ProcessException(ServerError.WRONG_LOGIN_PROVIDED.errorDTO());
}
}
However, understanding how exactly Collectors.toSet() could work under different conditions is really very useful.