The problem I’m facing is, when returning Optional i get null value.As I tought the purpose of Optional type is to avoid null values I’m a bit confused now.
This is my code:
PlayerController.java
@GetMapping("/{id}")
public Optional<Player> getPlayer(@PathVariable Long id) {
return playerService.getPlayerById(id);
}
PlayerService.java
public interface PlayerService {
List<Player> getAllPlayers();
Optional<Player> getPlayerById(Long id);
}
PlayerServiceImpl.java
@Override
public Optional<Player> getPlayerById(Long id) {
return playerRepository.findById(id);
}
When I test this using Postman, for players which id actually exists I get the player object but if I put a non existing id i get null
I’ve tried then checking if player object is null to return some kind of message like so:
@Override
public Optional<Player> getPlayerById(Long id) {
Optional<Player> player = playerRepository.findById(id);
if (player == null) { // warning
//some message
;
}
But when I wrote if statement I got a warning Condition 'player == null' is always 'false'
If the warning is true how do I get null from Postman ?
edit:
@Repository
public interface PlayerRepository extends JpaRepository<Player,
Long> {
}
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Version of Hibernate ismanaged by the Spring Boot parent dependency right ?
>Solution :
In Java, the Optional type is used to represent a value that might be present or absent. It helps avoid null values by providing methods to handle the absence of a value more gracefully. For example:
Optional<String> name = Optional.of("John");
Optional<String> emptyName = Optional.empty();
if (name.isPresent()) {
System.out.println("Name is present: " + name.get());
} else {
System.out.println("Name is not present");
}
if (emptyName.isPresent()) {
System.out.println("Name is present: " + emptyName.get());
} else {
System.out.println("Name is not present");
}
You can use methods like isPresent(), ifPresent(), or orElse() to work with the value in a safe manner, reducing the risk of NullPointerException.
From the above problem , The issue you’re facing is due to a misunderstanding of how Optional works. An Optional object itself is never null; it either contains a value or is empty. When you get a null response in Postman, it might be due to how the response is being handled in your controller.
PlayerController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
@RequestMapping("/players")
public class PlayerController {
@Autowired
private PlayerService playerService;
@GetMapping("/{id}")
public ResponseEntity<Player> getPlayer(@PathVariable Long id) {
Optional<Player> player = playerService.getPlayerById(id);
if (player.isPresent()) {
return ResponseEntity.ok(player.get());
} else {
return ResponseEntity.notFound().build();
}
}
}
Use of Optional as a return type in a Spring controllers, it’s not recommended. The primary reason is that Optional is intended for use within the application logic to handle the presence or absence of a value, not for use in API responses.
PlayerService.java
import java.util.List;
import java.util.Optional;
public interface PlayerService {
List<Player> getAllPlayers();
Optional<Player> getPlayerById(Long id);
}
==
PlayerServiceImpl.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class PlayerServiceImpl implements PlayerService {
@Autowired
private PlayerRepository playerRepository;
@Override
public List<Player> getAllPlayers() {
return playerRepository.findAll();
}
@Override
public Optional<Player> getPlayerById(Long id) {
Optional<Player> player = playerRepository.findById(id);
if (player.isPresent()) {
return player;
} else {
return Optional.empty();
}
}
}
