2015-11-13 184 views
0

我已經把兩個基本的類/表放在一起,以瞭解如何使用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

回答

1

這裏有幾個問題。 在車內,您有一個應該是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(這與可見性降低適用)我的應用程序崩潰。我編輯了我的答案以反映這兩點。 –

0

我已經設法得到這個工作。第一個問題是我的汽車類沒有展廳物業。第二個是我保存物體的方式似乎不正確。

我已將課程更改爲此..

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