Java Optional in class fields? Why not.
Tags: java, spring, functional
Published: 2018-10-26 00:26:54

---
title: Java Optional in class fields? Why not.
published: true
description: Using Java Optional in Spring Boot REST API DTOs
tags: Java, Spring, Functional
---


[Optional](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) was introduced in Java 8 and according to documentation it is
supposed to limit the use of `null` in return from the methods.

`Optional` class is not serializable so it is not intended to be used as fields
in Java beans.

As Brian Goetz stated on [Stack Overflow](https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type/26328555#26328555)
"routinely using it as a return value for getters would definitely be over-use."

I agree with the statement that they should be used with care and definitely not as a panacea for all problems.

I happened to see using `Optional` in such contexts like below to avoid using if-else statements in favour of more functional-style programming flow:

```
Optional.ofNullable(aField)
  .map(this::doSthWithTheField)
  .orElse(this::doSthElse)

```
versus old good imperative style:

```
if(aField==null){
  doSthWithTheField(aField);
}else{
  doSthElse(aField);
}
```

Is this usage of `Optional` already an overuse or not?

I think it's a matter of taste, pragmatism and an agreement in a team.
It's sort of messy in my oppinion if somestimes if-else and sometimes the structure like above is used around the single project cource code.

Personally I like more the version with `Optional`.

How about the crazy idea of using Optionals in your Domain Transfer Object (DTO)?

Or is it no so crazy at all?

Read further to check if this approach makes sense for you.

Imagine you have a business domain with a class `User` like below:
```
class User{
  private String name;
  private String secondName;

  public String getName(){
    return name;
  }
  public Optional<String> getSecondName(){
    return Optional.ofNullable(name)
  }

  // skipped setters for readability
}
```
Your `User` has attributes like `name` which is required (not null), and `secondName` which can be empty.
Having this, you do not need to worry anywhere else that you can get second name which is `null`.
E.g. you could use it like that:

```
User user = ...
String userName = user.getName();
String displayedName = user.getSecondName()
  .map(s-> userName + ", " + s)
  .orElse(userName);
```
instead of:
```
User user = ...
String userName = user.getName();
String second = user.getSecondName();
String displayedName = null;
if(second != null){
  displayedName = userName + ", " + second;
} else {
  displayedName = userName;
}
```

See the difference? Moreover, when you look at the domain class getters you already know which fields are optional, your code is self-documenting.

Now what if you need to pass such domain object in the response from a controller?

Usually you would probably like to wrap it in a Domain Transfer Object, like `UserResponse` but for simplicity, let's assume you will return `User` in the controller.

How will Spring know how to convert the  `Optional` value into JSON?
Well.. it won't by default. It would take the public getter method of the `Optional` class which is `isPresent()` and use it in JSON, e.g.:

```
{"name":"Marcin","secondName":{"present":true}}
```

To allow the correct conversion Jackson library has a module dedicated for Java 8 types.
Using Maven we need to ad this dependency:
```
<dependency>
   <groupId>com.fasterxml.jackson.datatype</groupId>
   <artifactId>jackson-datatype-jdk8</artifactId>
   <version>2.9.6</version>
</dependency>
```
and register it in `ObjectMapper` like this:

```
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
```

The good news is that if you're using Spring Boot with `spring-boot-starter-web` dependency then it already has everything configured and ready for use :)

![Spring dependencies](https://thepracticaldev.s3.amazonaws.com/i/uo1cinj62lx2cta81ia5.png)

[Here](https://github.com/piczmar/spring-boot-rest-optional-demo/tree/master) is a demo for this post.


If you liked it, you may also like other references:
* [https://dzone.com/articles/optionals-npes-and-design-practices](https://dzone.com/articles/optionals-npes-and-design-practices)
* [https://www.baeldung.com/jackson-optional](https://www.baeldung.com/jackson-optional)
* [https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring](https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring)
* [https://github.com/rzwitserloot/lombok/issues/1214](https://github.com/rzwitserloot/lombok/issues/1214)