Lymn
Lymn

Reputation: 75

Simple ManyToOne relation error on foreign key not nullable

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

Answers (1)

Brother
Brother

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

Related Questions