1

I have been trying to follow a tutorial and in which they are basically using java 7 and currently I am working on a java 8 environment so I would want to know what would be java8 version of the code that I am trying to work on - currently I am getting alot of errors using Optional which was suggested by eclipse to fix a few initial errors but I am stuck on some.

The java7 code as below:

@RequestMapping("/reservations")
    public Reservation updateReservation1(ReservationUpdateRequest request) {
        Reservation reservation = reservationRepo.findOne(request.getId());
        reservation.setNumberOfBags((request.getNumOfBags());
        reservation.setCheckedIn(request.getCheckedIn());
        return reservationRepo.save(reservation);
    }

java8 with error

@RequestMapping("/reservations")
    public Optional<Reservation> updateReservation(ReservationUpdateRequest request) {
        Optional<Reservation> reservation = reservationRepo.findById(request.getId());
        reservation.setNumberOfBags((request.getNumOfBags());
        reservation.setCheckedIn(request.getCheckedIn());
        return reservationRepo.save(reservation);
    }

here in java8 code eclipse ide is giving me error at line number 3 - that is when I am trying to set value into reservation.setNumberOfBags() it shows The method setNumberOfBags(int) is undefined for the type Optional<Reservation> - if any one can help ?

nightfury
  • 384
  • 6
  • 18
  • `reservation` is an `Optional` so you would have to call `get` method to get the actual value. However you should first use `isPresent` to check if value underneath is not null and apply processing based on this condition. – Michał Krzywański Apr 21 '19 at 09:48
  • 1
    I'd like to add that your REST is very bad. You shouldn't use Request objects. `@PutMapping(value="/reservations/{resId}") public Optional updateReservation(Reservation patchReservation, @PathParameter int resId) {` – f.khantsis Apr 21 '19 at 09:50
  • 3
    You're trying random things. That won't lead you anywhere. Instead, read the javadoc of Optional. Google to find articles explaining what an Optional is and how to use it (there are plenty of them). The whole point of Optional is to **force** you to think about what you should do if the entity with the given ID doesn't exist. So you have to make that decision first. – JB Nizet Apr 21 '19 at 09:50
  • 1
    @michalk that's actually an anti-pattern to use Optional by using isPresent/get pattern (unless there's no other way). Processing should happen by delegating optionality checks to the Optional itself by using map/flatMap/filter – Grzegorz Piwowarek Apr 21 '19 at 09:57
  • @JBNizet - definitely will work it that way. – nightfury Apr 21 '19 at 11:16
  • @f.khantsis - I am new to REST - would want to know why is it so. and how does using `@PutMapping` makes a difference ? – nightfury Apr 21 '19 at 11:18
  • 1
    @manisjos because an update operation should use a `PUT` http verb, and not a `GET` which is the default for `RequestMapping` – f.khantsis Apr 21 '19 at 11:49

2 Answers2

4

You should return Reservation instead of Optional<Reservation> (I guess you're using Spring Data, see the save method).

If you want to throw an exception when the reservation is not found, use:

public Reservation updateReservation(ReservationUpdateRequest request) {
        Reservation reservation = reservationRepo.findById(request.getId())
            .orElseThrow(() -> new EntityNotFoundException("Reservation not found"));
        reservation.setNumberOfBags(request.getNumOfBags());
        reservation.setCheckedIn(request.getCheckedIn());
        return reservationRepo.save(reservation);
    }

In case you want to return a 404 error code when it's not found:

public ResponseEntity<Reservation> updateReservation(ReservationUpdateRequest request) {
     return reservationRepo.findById(request.getId())
         .map(r -> {
              r.setNumberOfBags(request.getNumOfBags());
              r.setCheckedIn(request.getCheckedIn());
              return ResponseEntity.ok().body(reservationRepo.save(r));
          }).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

And the RequestMapping is weird, you should use PUT with the id in the URL instead of request body.

@PutMapping("/reservations/{id}")
public ResponseEntity<Reservation> updateReservation(@PathParam("id") Long id, ReservationUpdateRequest request) {
     return reservationRepo.findById(id)
         .map(r -> {
             r.setNumberOfBags(request.getNumOfBags());
             r.setCheckedIn(request.getCheckedIn());
             return ResponseEntity.ok().body(reservationRepo.save(r));
         }).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
1
@RequestMapping("/reservations")
public Optional<Reservation> updateReservation(ReservationUpdateRequest request) {
    Optional<Reservation> reservation = reservationRepo.findById(request.getId());
    if(reservation.isPresent()) {
        Reservation actReservation = reservation.get();
        actReservation .setNumberOfBags((request.getNumOfBags());
        actReservation .setCheckedIn(request.getCheckedIn());
        return reservationRepo.save(actReservation );
    }
    else {
        return Optional.empty();
    }
}
f.khantsis
  • 3,256
  • 5
  • 50
  • 67