Pages

Thursday, September 10, 2020

Java Optional as Return Type

1. Overview

In this article, you'll learn how to use Optional as a return type in java 8.  Let us explore the most useful methods when working with Optional objects.

And also where Option can not fit and the scenarios where you should not use Optional in java.

Optional is added in java 8 to make clean the code and to easy way to work with the null values.

Let us jump into the Optional return type and its most important methods.

We've already covered in-depth about Optional API

Java Optional as Return Type


2. Optional As Return Type

When you are expecting Optional as return type then the returned object may have the value or null value.

In both cases, you should use the right methods of Optional such as ofNullable(), ifPresent() and get().

package com.javaprogramto.java8.streams.optionals.returntype;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class OptionalReturnExample {

	private static Map<Integer, String> idNames = new HashMap<>();

	public static void main(String[] args) {

		idNames.put(100, "jacowith");
		idNames.put(200, "Hemon");
		idNames.put(300, "Suwaari");
		idNames.put(400, "Meanon");
		idNames.put(500, "Zulia");

		Optional<String> id300Name = getNameById(300);

		if (id300Name.isPresent()) {
			String value = id300Name.get();
			System.out.println("id 300 name : " + value);
		}

		Optional<String> idUnknown = getNameById(700);

		if (idUnknown.isPresent()) {
			String value = idUnknown.get();
			System.out.println("id 700 name : " + value);
		} else {
			System.out.println("id 700 is unknown  one");
		}

	}

	public static Optional<String> getNameById(int id) {

		String name = idNames.get(id);

		Optional<String> nameOptional = Optional.ofNullable(name);

		return nameOptional;
	}

}
 

Output:

id 300 name : Suwaari
id 700 is unknown  one
This code never throws any exception and you can use the return type Optional always.There is a another method ifPresent() and ifPresentOrElse() methods that takes Consumer functional interface.
getNameById(400).ifPresent(value -> System.out.println("id  400 value is  : " + value));
		
getNameById(900).ifPresentOrElse(value -> System.out.println("id  900 value is  : " + value),
				() -> System.out.println("id 900 not found"));
 

This is good practice to use it as a return type but there are a few situations that should not be used.

3.  When To Not Use Optional

There are some situations where really Optional should not be used and will create the data loss.

3.1 Serialization

Look at the below class which wraps the Salary in Optional.

This class is implementing the Serializable interface.

import java.io.Serializable;
import java.util.Optional;

public class Employee implements Serializable {

	private int id;
	private String name;
	private Optional<Long> salary;
	
	//  setters and  getters

}

 

When you do serialize this employee object with an optional object then it will produce the NotSerializableException at runtime.

Because the Optional class does not implement the Serializable interface. So, the Serialization process does not know how to serialize it and produce an error.

It is good practice to avoid Optional in serialization.

3.2 JSON - Jackson API

Nowadays many applications provide several services and those are based on the rest api. All of this request and responses are exposed in the form of JSON using Jackson API.

How to convert JSON to an Object in java?

When you are developing the api,  you should not use the Optional as the return type for any json attributes as below.

	
private String name;

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

public void setName(String name) {
	this.name = name;
}


Here, you are expecting the String type for the name field in the form of Optional. This is not known to the service caller on how to send in the json as Optional. It is pain to use Optional with JSON.

3.3 JPA Entity

When you. are working with Hibernate or any ORM framework, you use the Entity classes annotated with @Entity annotation.

In the entity class, you'll declare the fields that match the database column names and data types as well.

But what happens if you declare any column with Optional as below.

@Entity
public class Employee implements Serializable {
    @Id
    private long id;
 
    private Optional<String> firstName;
	
	// other fields
 
    // ... getters and setters
}
 

Now, let us add. the employee records into the database using the persist() method.

Employee emp = new Employee();
emp.setId(1l);
emp.setFirstName(Optional.of("javaprogramto.com"));
entityManager.persist(emp);
 

Further, when you run the program, it will throw the PersistenceException.

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: com.javaprogramto.Employee] Unable to build Hibernate SessionFactory
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1015)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:941)
	at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
	at com.javaprogramto.Employee.PersistOptionalTypeExample.<clinit>(PersistOptionalTypeExample.java:11)
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Optional, at table: Employee, for columns: [org.hibernate.mapping.Column(firstName)]
 

But instead of declaring the field as Optional, you can use the getter method returns the Optional<String> value using Optional.ofNullable(this.firstName).

Even though it is not recommended to use and breaks the traditional approach.

4. Conclusion

In this article, you have seen how to use Optional as a return type in java 8.

What are the other areas not suggested to use? such as serialization, JSON, JPA, and expression language.

Examples are over GitHub.

Optional API

Ref

No comments:

Post a Comment

Please do not add any spam links in the comments section.