1

I need to pass dateTs from rest controller class-method into getCars() method in the service class which will retrieve cars that were registered on the given timestamp date and if the timestamp dateTs(its Optional) is null then it will retrieve all cars. I think current implementation will not work since if dateTs is null then it can't be passed into getCars() which expects value of type Long. Where and how should I check if the dateTs is not null and how to pass corresponding value into getCars() and invoke appropriate method?

@GetMapping(value = "/get/cars")
public CarList CarController(@Param("dateTs") Optional<Long> dateTs) {
   
return ResponseEntity.ok(carService.getCars((Long) dateSt.get());
} 

Service class method:

public List<Car> getCars(Long dateSt) {
   List<Car> carList; 
  
   if(dateSt != null){
       carList = carReposistory.retrieveRegisteredCars(dateSt);}
   else{
      carList = carReposistory.retrieveAllCars();} 
       
   return carList;
}
lczapski
  • 4,026
  • 3
  • 16
  • 32
Mar
  • 363
  • 1
  • 3
  • 10
  • null can be passed to getCars as Long is an object, you would have a problem with long (native type) – vmrvictor Feb 09 '21 at 20:09
  • Not sure what you meant by "long (native type)" ? I have to use ` dateTs`. So you are saying that Long without value attached is still an object. `dateTs` is an optional value so if no value is provided then I assume Long object without value can be further processed and passed. Will dateSt.get() cause any issues if its null? – Mar Feb 09 '21 at 20:26
  • well I recommed you to read javadocs, https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html for get "If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.", so yes, you will have an exception thrown as you can see in some answers you can use orElse(null) – vmrvictor Feb 09 '21 at 20:55

3 Answers3

3

Just a note: a Long can be null, so it can be passed to getCars(Long). It is a long that cannot be null, since it is a primitive.

The problem probably is that Optional#get() throws a NoSuchElementException if there is no value in the Optional (its value is null), you could have used Optional#orElse() like in:

return ResponseEntity.ok(carService.getCars((Long) dateSt.orElse(null));

using Optional#isPresent(), as other answer are suggesting, is a (probably better) option.

For reference, check the documentation of orElse.


Note 2: also check this question and its answers: Why should Java 8's Optional not be used in arguments

2

You can do it in two way. With passing Optional to getCars or without. With passing:

public List<Car> getCars(Optional<Long> dateSt) {
   if(dateSt.isPresent()){
       return carReposistory.retrieveRegisteredCars(dateSt.get());
   }
   return carReposistory.retrieveAllCars(); 
}

Without passing: you have to create two separated methods:

public List<Car> retrieveRegisteredCars(Long dateSt) {
   return carReposistory.retrieveRegisteredCars(dateSt);
}

public List<Car> retrieveAllCars() {
   return carReposistory.retrieveAllCars(); 
}

and use them in controller:

return ResponseEntity.ok(
  dateSt.map(carService::retrieveRegisteredCars)
  .orElseGet(() -> carService.retrieveAllCars())
);

UPDATE

Or just pass null

return ResponseEntity.ok(carService.getCars((Long) dateSt.orElse(null)));
lczapski
  • 4,026
  • 3
  • 16
  • 32
2

You usually don't want to pass Optionals as parameters, however I don't know if it applies to REST controllers. See this

Now that this is said, you should have two methods in your service, one for when it's present, one when it's absent.

Controller

@GetMapping(value = "/get/cars")
public CarList CarController(@Param("dateTs") Optional<Long> dateTs) {
    return ResponseEntity.ok(
               dateTs.map(carService::getRegisteredCars)
                     .orElseGet(carService::getAllCars)
           );
} 

Service

public List<Car> getRegisteredCars(Long dateSt) {
    return carReposistory.retrieveRegisteredCars(dateSt);
}

public List<Car> getAllCars() {
    return carReposistory.retrieveAllCars();
}
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89