77jt777
77jt777

Reputation: 69

Spring JPA data base doesn't seen to refresh values that were set to the object in POST method

I'm trying to set some values to certain object if some contidions are true. It seems like code executes and reaches the "set" lines, but when I send POST request(where this logic is implemented) and then GET method, it seems like it hasn't updated this object.

This is my Car class:

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;

@Data
@Entity
@Table(name = "Cars")
public class Car {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Setter(AccessLevel.NONE)
    private Long Id;

    private int yearOfProduction;
    private int price;
    private String color;
    private String brand;
    private String model;

    @ManyToOne
    @JoinColumn(name = "owner")
    @ToString.Exclude
    private Customer owner;

    public Car() {
    }

    public Car(int yearOfProduction, int price, String color, String brand, String model) {
        this.yearOfProduction = yearOfProduction;
        this.price = price;
        this.color = color;
        this.brand = brand;
        this.model = model;
    }
}

This is my Customer class:

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

import javax.persistence.*;
import java.util.List;


@Data
@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Setter(AccessLevel.NONE)
    private Long Id;

    private String firstName;
    private String lastName;
    private String email;
    private String phoneNumber;
    private int amountOfCash;
    private int actualDiscount;

    @OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
    private List<Car> carList;

    public Customer(String firstName, String lastName, String email, String phoneNumber, int amountOfCash, int actualDiscount) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.phoneNumber = phoneNumber;
        this.amountOfCash = amountOfCash;
        this.actualDiscount = actualDiscount;
    }

    public Customer() {
    }


}

This is my POST method when I implement the logic:

public ResponseEntity<Customer> buyCar(Long customerID, Long carID) {
        customerRepository
                .findById(customerID)
                .ifPresentOrElse(customer -> {
                    carRepository.findById(carID).ifPresentOrElse(car -> {
                        if (customer.getAmountOfCash() > car.getPrice() * (100 - customer.getActualDiscount()) / 100) {
                            customer.getCarList().add(car);
                            customer.setActualDiscount(customer.getActualDiscount() + 5);
                            customer.setAmountOfCash(customer.getAmountOfCash() -
                                     car.getPrice()* (100 - customer.getActualDiscount()) / 100);
                            car.setOwner(customer);
                        } else {
                            throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,
                                    "Customer doesn't have enough cash");
                        }
                    }, () -> {
                        throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Car not found");
                    });
                }, () -> {
                    throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found");
                });
        return new ResponseEntity<>(HttpStatus.OK);
    }

This is my GET method:

   public List<Customer> getCustomers() {
        return customerRepository.findAll();
    }

I also want to add that when I've tried to add the customer once again to the data base like this: customerRepository.save(customer) in POST method, and then I used GET method. The fields have been updated except of the carList, this one was still empty. Also when I print the customer to the console, all of the fields are updated, even carList.

Upvotes: 0

Views: 667

Answers (1)

Jo&#227;o Dias
Jo&#227;o Dias

Reputation: 17500

You need to set cascade on your @OneToMany annotation as CascadeType.PERSIST):

@Data
@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Setter(AccessLevel.NONE)
    private Long Id;

    private String firstName;
    private String lastName;
    private String email;
    private String phoneNumber;
    private int amountOfCash;
    private int actualDiscount;

    @OneToMany(mappedBy = "owner", fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private List<Car> carList;

    public Customer(String firstName, String lastName, String email, String phoneNumber, int amountOfCash, int actualDiscount) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.phoneNumber = phoneNumber;
        this.amountOfCash = amountOfCash;
        this.actualDiscount = actualDiscount;
    }

    public Customer() {
    }
}

This will trigger also the persistence of the Car objects in the carList property of Customer.

There are other cascade types that might be interesting in your use case, so please take a look at the following resources:

In addition, add @Transactional to your public ResponseEntity<Customer> buyCar method as follows:

@Transactional
public ResponseEntity<Customer> buyCar(Long customerID, Long carID) {
    customerRepository
        .findById(customerID)
        .ifPresentOrElse(customer -> {
            carRepository.findById(carID).ifPresentOrElse(car -> {
                if (customer.getAmountOfCash() > car.getPrice() * (100 - customer.getActualDiscount()) / 100) {
                    customer.getCarList().add(car);
                    customer.setActualDiscount(customer.getActualDiscount() + 5);
                    customer.setAmountOfCash(customer.getAmountOfCash() -
                             car.getPrice()* (100 - customer.getActualDiscount()) / 100);
                    car.setOwner(customer);
                } else {
                    throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,
                            "Customer doesn't have enough cash");
                }
            }, () -> {
                throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Car not found");
            });
        }, () -> {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found");
        });
    return new ResponseEntity<>(HttpStatus.OK);
}

Upvotes: 2

Related Questions