休眠关系外键约束失败

问题描述:

我已经把两个基本的类/表放在一起,以了解如何使用Hibernate。休眠关系外键约束失败

一旦执行下面的代码;

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(); 

我得到这个错误;

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

我不太确定它出错的地方。这里是两个带注释的类;

@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; 
    } 
} 

暂时我让Hibernate在MySQL数据库中创建表。我已经检查过并且数据库之间的关系确实存在于Car表中。

有人能告诉我为什么这不起作用吗?

我猜这是因为陈列室没有Id,因为这是由MySQL自动生成的,所以汽车无法保存?是对的吗?

+0

所以,如果我先救展厅(不含汽车),确保我抢insertId并将此作为id的陈列室,汽车再次添加到展厅和保存(更新),这应该插入有展厅ID的汽车? – SheppardDigital

+1

查看本教程:http://alextretyakov.blogspot.hk/2013/07/jpa-many-to-many-mappings.html –

+0

谢谢,我来看看。 – SheppardDigital

这里有几个问题。 在车内,您有一个应该是FK参考陈列室的字段。但是,这是一个本地int。这意味着它的值为零。 如果你的车对象应引用您的陈列室,那么你就必须用@ManyToOne

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

然后你在陈列室改变字段添加到

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

的引用。如果你这样做,你需要明确地在Car中设置参考。 无论哪种方式,showroomId(也是一个本地int)需要去。要么你不应该在你的Car对象中拥有这个字段,并且你只有backref List,否则你需要用正确映射的Entity引用替换它(见上面)。

另一个问题是您生成的列是本机类型。这成为0的值,并且Hibernate不会自动/正确地生成该值。

更改两个实体的主键引用(与getter和setter一起)

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

为了从DB成功加载的实体,我也不得不增加一个默认的构造函数用于汽车。

protected Car() { 
} 

然后你的例子将工作。

+0

我尝试了你的建议,并在执行后返回错误“标记为mappedBy的关联不能像@JoinTable或@JoinColumn那样定义数据库映射” – SheppardDigital

+0

糟糕。是的。 JoinColumn注释属于Car对象内部的Showroom字段定义。我还必须在Car对象内部添加一个默认构造函数,然后才能从数据库加载它们。随着默认consructor(这与可见性降低适用)我的应用程序崩溃。我编辑了我的答案以反映这两点。 –

我已经设法得到这个工作。第一个问题是我的汽车类没有展厅物业。第二个是我保存物体的方式似乎不正确。

我已将课程更改为此..

@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; 
    } 
} 

现在保存功能;

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();