Witam, zmagam się właśnie ze stworzeniem aplikacji "wypożyczalni aut" w Spring Boocie, która łączyłaby się moją bazą danych, i za pomocą Postmana i prostych metod GET i POST, dodawałaby oraz wyświetlała dane z tabel. Wszystko działa ok dla klas Clients oraz Cars (rekordy są dodawane bezproblemowo), ale aplikacja "sypie się" gdy próbuję dodać rekord do tabeli Rentals, czyli zawierającej zamówienia, w której zawarte są foreign key'e dla id klienta i samochodu.
Rental entity class:
@Entity
@Table(name="rentals")
public class Rentals {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private Date rental_date;
private String status;
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@PrimaryKeyJoinColumn(name="client_id")
private Clients client;
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@PrimaryKeyJoinColumn(name="car_id")
private Cars car;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Clients getClient() {
return client;
}
public void setClient(Clients client) {
this.client = client;
}
public Cars getCar() {
return car;
}
public void setCar(Cars car) {
this.car = car;
}
public Date getRental_date() {
return rental_date;
}
public void setRental_date(Date rental_date) {
this.rental_date = rental_date;
}
}
Clients entity class:
@Entity
@Table(name="clients")
public class Clients {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer client_id;
public Integer getClient_id() {
return client_id;
}
public void setClient_id(Integer client_id) {
this.client_id = client_id;
}
private String name,surname,place_of_residence,id_number;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getPlace_of_residence() {
return place_of_residence;
}
public void setPlace_of_residence(String place_of_residence) {
this.place_of_residence = place_of_residence;
}
public String getId_number() {
return id_number;
}
public void setId_number(String id_number) {
this.id_number = id_number;
}
}
Cars entity class:
@Entity
@Table(name="cars")
public class Cars {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer car_id;
private String brand,model,licence_plate_number,production_year,price_per_day;
public Integer getCar_id() {
return car_id;
}
public void setCar_id(Integer car_id) {
this.car_id = car_id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getLicence_plate_number() {
return licence_plate_number;
}
public void setLicence_plate_number(String licence_plate_number) {
this.licence_plate_number = licence_plate_number;
}
public String getProduction_year() {
return production_year;
}
public void setProduction_year(String production_year) {
this.production_year = production_year;
}
public String getPrice_per_day() {
return price_per_day;
}
public void setPrice_per_day(String price_per_day) {
this.price_per_day = price_per_day;
}
}
Poniżej klasa będąca kontrolerem dla metod GET i POST (RentalsController):
@RestController
@RequestMapping("/rentals")
public class RentalsController {
private final RentalsRepository rentalsRepository;
public RentalsController(RentalsRepository rentalsRepository){
this.rentalsRepository = rentalsRepository;
}
@RequestMapping(method = RequestMethod.POST)
public void addRental(@RequestBody Rentals rental){
rentalsRepository.save(rental);
}
@RequestMapping(method = RequestMethod.GET)
public List<Rentals> getRentals(){
return rentalsRepository.findAll();
}
}
Zapytanie JSON które kieruję do bazy:
{
"client_id":2,
"car_id":4,
"rental_date":"2017-06-05",
"status":"rented"
}
Oraz stacktrace dla errora (skrócona wersja ze względu na ograniczoną liczbę znaków posta), który wyrzuca kompilator:
2017-06-14 11:02:57.893 WARN 3932 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000
2017-06-14 11:02:57.894 ERROR 3932 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'car_id' cannot be null
2017-06-14 11:02:57.898 ERROR 3932 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'car_id' cannot be null
Problem leży moim zdaniem w mapowaniu kluczy obcych, w klasie Rentals (entities), ale próbowałem już na wiele sposobów, przy użyciu adnotacji @JoinColumn, @PrimaryKeyJoinColumn oraz z samą adnotacją @OneToOne, ale żaden ze sposobów nie pomógł.
Będę ogromnie wdzięczny za jakiś pomysł, lub dobry tutorial który będzie traktował o mapowaniu tabeli relacyjnej w SpringBoocie. Z góry dzięki za pomoc!