简体   繁体   中英

Hibernate relationship foreign key constraint fails

I've put together two basic classes/tables in order to learn how the use Hibernate.

Upon execution of the following code;

Session hbSession = HibernateUtil.getSession();

        Showroom showroom = new Showroom();
        showroom.setLocation("London");
        showroom.setManager("John Doe");

        List<Car> cars = new ArrayList<Car>();
        cars.add(new Car("Vauxhall Astra", "White"));
        cars.add(new Car("Nissan Juke", "Red"));

        showroom.setCars(cars);

        hbSession.beginTransaction();
        hbSession.save(showroom);
        hbSession.getTransaction().commit();

I'm getting this error;

Cannot add or update a child row: a foreign key constraint fails (`ticket`.`Car`, CONSTRAINT `FK107B4D9254CE5` FOREIGN KEY (`showroomId`) REFERENCES `Showroom` (`id`))

I'm not really sure where it's going wrong. Here are the two annotated classes;

@Entity
public class Showroom {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @OneToMany
    @JoinColumn(name="showroomId")
    @Cascade(CascadeType.ALL)
    private List<Car> cars = null;

    private String manager = null;
    private String location = null;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public List<Car> getCars() {
        return cars;
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }

    public String getManager() {
        return manager;
    }

    public void setManager(String manager) {
        this.manager = manager;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}

@Entity
public class Car {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private String color;
    private int showroomId;

    public Car(String name, String color) {
        this.setName(name);
        this.setColor(color);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getShowroomId() {
        return showroomId;
    }

    public void setShowroomId(int showroomId) {
        this.showroomId = showroomId;
    }
}

For the time being I've let Hibernate create the tables in the MySQL database. I've checked and the relationship between the database does exist in the Car table.

Is anyone able to tell my why this isn't working?

At a guess I'm saying it's because the showroom doesn't have an Id, as this is auto-generated by MySQL, so the cars cannot be saved? Is that right?

You have a couple problems here. In Car, you have a field that is supposed to be a FK reference to the Showroom. However, this is a native int. That means that it has a value of zero. If your Car object should reference your Showroom, then you would have to add a reference with @ManyToOne

@ManyToOne
@JoinColumn(name="showroomId")
private Showroom showroom;

Then your field in Showroom changes to

@OneToMany(mappedBy = "showroom")
@Cascade(value = { org.hibernate.annotations.CascadeType.ALL } )
private List<Car> cars = null;

If you do this, you need to set the reference in Car explicitly. Either way, the showroomId (also a native int) needs to go. Either you shouldn't have the field in your Car object at all, and you have only the backref List, or you need to replace it with a properly mapped Entity reference (see above).

The other problem is that your generated Column is a native type. This becomes a value of 0, and Hibernate will not automatically/correctly generate the value.

Change your primary key reference in both Entities (along with the getters and setters)

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}

In order to load the entities successfully from the DB, I also had to add a default constructor for Car.

protected Car() {
}

Then your example will work.

I've managed to get this working. The first problem was that I didn't have a showroom property in my Car class. The second was the way I was saving the objects didn't seem to be correct.

I've altered my classes to this..

@Entity
public class Showroom {

    @Id
    @GeneratedValue
    private int id;

    private String location;
    private String manager;

    @OneToMany(mappedBy="showroom")
    private List<Car> cars;

    public List<Car> getCars() {
        return cars;
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }
}

@Entity
public class Car {

    @Id
    @GeneratedValue
    private int Id;

    private String name;
    private String color;

    @ManyToOne
    @JoinColumn(name="showroomId")
    private Showroom showroom;

    public Car(String name, String color) {
        this.name = name;
        this.color = color;
    }
}

And the save functions are now;

Session hbSession = HibernateUtil.getSession();
        hbSession.beginTransaction();

        // Create a showroom
        Showroom showroom = new Showroom();
        showroom.setManager("John Doe");
        showroom.setLocation("London");
        hbSession.save(showroom);

        // Create car one, assign the showroom and save
        Car car1 = new Car("Vauxhall Astra", "White");
        car1.setShowroom(showroom);
        hbSession.save(car1);

        // Create car two, assign the showroom and save
        Car car2 = new Car("Nissan Juke", "Red");
        car2.setShowroom(showroom);
        hbSession.save(car2);

        hbSession.getTransaction().commit();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM