Reputation: 75
Using spring boot and hibernate annotations, I want a Depot to contain multiple BusVehicle in a many to one relationship. BusVehicules can also not be assigned to Depot, marking their foreign key as null. From what I read, it should be nullable by default but I get the following error when trying to insert my item :
There was an unexpected error (type=Internal Server Error, status=500).
could not execute statement; SQL [n/a]; constraint ["FK9ORG94PEJ62WYIS4QS1F2WCP7: PUBLIC.BUSVEHICULE FOREIGN KEY(ID) REFERENCES PUBLIC.DEPOT(ID) (1)"; SQL statement: insert into busvehicule (id, busvehicule_color, fk_depot_id, busvehicule_passengercapacity, busvehicule_platenumber, busvehicule_type) values (null, ?, ?, ?, ?, ?) [23506-199]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
I tried adding annotations like nullable = true or optional=true but nothing changed. I am using H2 database.
BusVehicle:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(optional=true)
@JoinColumn(name ="FK_depotId", nullable = true)
private Depot depotParkedIn;
Depot:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "DEPOT_BUSVEHICULESPARKED")
@OneToMany(mappedBy="id", cascade = CascadeType.DETACH, fetch=FetchType.EAGER)
private Set<BusVehicle> busVehiclesParked = new HashSet<BusVehicle>();
h2 management:
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:test
The code saving the object:
@Autowired
BusVehicleRepository busVehiculeRepository;
@PostMapping("/createbusvehicle")
public String checkAndCreateBusVehicle (BusVehicle newBusVehicle, Model model) {
if (!BusVehiculeWrapper.ValidateBusVehicle(newBusVehicle)) {
return "createBusVehicle";
}
busVehiculeRepository.save(newBusVehicle);
return "mainpage";
}
busVehiculeRepository:
@Repository
public interface BusVehicleRepository extends JpaRepository<BusVehicle, Long> {
public List<BusVehicle> findByDepotParkedInNull();
}
It fails on the save method from the repository after passing my custom validation (that does not check that depot is not null, as this is expected.)
Upvotes: 0
Views: 554
Reputation: 2220
Your problem is here:
@OneToMany(mappedBy="id", cascade = CascadeType.DETACH, fetch=FetchType.EAGER)
private Set<BusVehicle> busVehiclesParked = new HashSet<BusVehicle>();
This field "mappedBy" is to say:
On class BusVehicle, which field is referring to my class?
If we look in your class "BusVehicle", the field referring is (depotParkedIn):
@ManyToOne
@JoinColumn(name ="FK_depotId")
private Depot depotParkedIn;
So, try changing to:
@OneToMany(mappedBy="depotParkedIn", cascade = CascadeType.DETACH, fetch=FetchType.EAGER)
private Set<BusVehicle> busVehiclesParked = new HashSet<BusVehicle>();
FYI: Just tested locally with both implementations, and with the change here, it all worked.
Upvotes: 1