2015-11-13 2 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. Я проверил, и связь между базой данных существует в таблице автомобилей.

Может ли кто-нибудь сказать мне, почему это не работает?

Угадайте, я говорю, это потому, что в салоне нет идентификатора, так как это автоматически генерируется MySQL, поэтому автомобили не могут быть сохранены? Это правильно?

+0

Так что, если я экономлю шоу-рум первый (без авто), убедитесь, что я хватаю insertId и установить это как Id на шоу, добавлять автомобили в салон и сохранить (обновление) опять же, это должно вставить автомобили с автосалонами id? – SheppardDigital

+1

см. Этот учебник: http://alextretyakov.blogspot.hk/2013/07/jpa-many-to-many-mappings.html –

+0

Спасибо, я посмотрю. – SheppardDigital

ответ

1

У вас здесь пара проблем. В автомобиле у вас есть поле, которое должно быть ссылкой FK на Showroom. Однако это родной int. Это означает, что он имеет значение 0. Если объект Car должен ссылаться на свой Showroom, то вы должны добавить ссылку с @ManyToOne

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

Тогда ваше поле в изменениях Showroom в

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

Если вы сделаете это, вы должны задайте ссылку в автомобиле явно. В любом случае, вам необходимо пойти на выставку (также родной int). Либо у вас не должно быть поля в вашем объекте Car вообще, и у вас есть только список backref, или вам нужно заменить его правильно сопоставленной ссылкой Entity (см. Выше).

Другая проблема заключается в том, что созданная колонка является нативным типом. Это становится значением 0, а Hibernate не будет автоматически/правильно генерировать значение.

Изменение первичного ключа ссылки в обоих образованиях (вместе с добытчиками и сеттеров)

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

Для того, чтобы успешно нагрузить объекты из БД, я должен был добавить конструктор по умолчанию для автомобиля.

protected Car() { 
} 

Тогда ваш пример будет работать.

+0

Я попробовал ваше предложение, и после его выполнения он возвращает ошибку «Ассоциации, помеченные как mappedBy, не должны определять сопоставления базы данных, такие как @JoinTable или @JoinColumn» – SheppardDigital

+0

К сожалению. Ага. Аннотирование JoinColumn принадлежит внутри объекта Car, в определении поля Showroom. Мне также пришлось добавить конструктор по умолчанию внутри объекта Car, прежде чем я смог загрузить их из БД. С коннектором по умолчанию (который работает нормально с уменьшенной видимостью) мое приложение разбилось. Я отредактировал свой ответ, чтобы отразить эти два момента. –

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