Home > other >  Optional in builder pattern, get()
Optional in builder pattern, get()

Time:05-04

I'm working on a backend for a web application in Java (using Spring) und try to use the builder pattern. I have the classes

  • Example (as a Data object)
  • ExampleDocument (as another Data object)
  • ExampleMapper
  • ExampleRepository (extends MongoRepository)
  • ExampleController(REST)
  • ExampleService

Now I have a problem with a function returning an Optional (findById, Mongo-Repo) to my service:

@Service
@RequiredArgsConstructor
public class ExampleService {

    private final ExampleMapper exampleMapper;
    private final ExampleRepository exampleRepository;


    public Example getExample(String exampleId) {
        Optional<ExampleDocument> document = exampleRepository.findById(exampleId);
        return exampleMapper.mapToDto(document);
    }

I want to map the document in my mapper class as I'm used to do it with other documents (without the Optional it looks like this, I took an example from another class:

@Component
public class OtherExampleMapper {

    public OtherExample mapToDto(OtherExampleDocument document) {
        return OtherExample.builder()
                .id(document.getId())
                .existingSolutions(document.getExistingSolutions())
                ...
                .build();
    }

)

I tried to use ifPresent, but the builderPattern seems not to recognize the expression, since I have a yellow mark on "getId()", telling me "Result of 'PitchEventDocument.getId()' is ignored" and a red mark on ".build()"

@Component
public class PitchEventMapper {
public Example mapToDto(Optional<ExampleDocument> document) {
        return Example.builder()
                .id(document.ifPresent(id -> document.get().getId())
                .build();
    } 

How can I still use the builder pattern in combination with the Optional?

CodePudding user response:

Your basic problem is that ifPresent doesn't return a value at all—it's void. Instead, you want orElse (since I think you want null or another default value in that case), and you shouldn't use get—all the relevant "if" and "or" methods already unwrap the value for you.

Instead:

Example.builder()
  .id(document.map(Document::getId).orElse(null))
  .build()
  • Related