Спящий режим «многие к одному» без внешнего ключа, но с обратным внешним ключом

У меня есть следующая БД:

CREATE TABLE car_owner (
  car_owner_id int(11) NOT NULL,
  car_id_fk int(11) DEFAULT NULL,
  PRIMARY KEY (car_owner_id),
  KEY car_owner_car_fk_idx (car_id_fk),
  CONSTRAINT car_owner_car_fk FOREIGN KEY (car_id_fk) REFERENCES car (car_id) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


CREATE TABLE car (
   car_id int(11) NOT NULL AUTO_INCREMENT,
   car_type varchar(45) DEFAULT NULL,
   car_plates varchar(25) DEFAULT NULL,
  PRIMARY KEY (car_id),
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

И в модели Java:

Для CarOwner у меня есть:

@Entity
@Table(name="car_owner")
@NamedQuery(name="CarOwner.findAll", query="SELECT co FROM CarOwner co")
public class CarOwner implements Serializable {

    @Id
    @GeneratedValue
    @Column(name="car_owner_id")
    private Integer carOwnerId;
.....

    //bi-directional many-to-one association to Car
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "car_id_fk", referencedColumnName = "car_id")
    private List<Car> cars;

И для автомобиля:

@Entity
@Table(name="car")
@NamedQuery(name="Car.findAll", query="SELECT c FROM Car c")
public class Car implements Serializable {

    @Id
    @GeneratedValue
    @Column(name="car_id")
    private Integer carId;
......

    //bi-directional many-to-one association to car_owner
    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name = "car_owner_id")
    private CarOwner carOwner;

Проблема здесь в том, что Hibernate не может связать таблицы и автоматически создает новые столбцы car_id и car_owner_id в таблице car.

Может ли кто-нибудь помочь найти правильную комбинацию в модели, чтобы правильно связать таблицы.


person GingerHead    schedule 26.05.2015    source источник


Ответы (1)


@JoinColumn должен быть в отношениях владельца (в отношениях один ко многим многие стороны считаются владельцем).

Поэтому я изменю это в car

 @ManyToOne(fetch=FetchType.EAGER)
 @JoinColumn(name = "car_owner_id",insertable=false, updatable=false)
 private CarOwner carOwner;

И это в CarOwner

@OneToMany(fetch = FetchType.EAGER,mappedBy = "carOwner")
 private List<Car> cars;

В качестве примечания я бы также не использовал EAGER, но это не имеет ничего общего с вопросом.


Обе таблицы знают друг о друге, что называется двунаправленной связью. Это происходит, когда каждая таблица имеет ключ к другой таблице. Это то, что ожидает ваш Java-код. Однако ваши таблицы в базе данных имеют однонаправленную связь. Это означает, что одна таблица знает о другой, но не об обеих. Ваш car_owner знает о car из-за внешнего ключа CONSTRAINT car_owner_car_fk FOREIGN KEY, но ваш car не имеет ни малейшего представления о car_owner, и то, и другое совершенно верно.

Теперь проблема в том, что в вашем Java-коде вы рассматриваете его как двунаправленную связь.

//bi-directional many-to-one association to car_owner
 @ManyToOne(fetch=FetchType.EAGER)
 @JoinColumn(name = "car_owner_id")
 private CarOwner carOwner;

но у автомобиля нет car_owner_id почему вы рассматриваете его как двунаправленную связь.

Теперь либо обновите базу данных, чтобы сделать их би, либо измените код Java.

person Shahzeb    schedule 26.05.2015
comment
Я получаю это исключение: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'car0_.car_owner_id' in 'field list' sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) - person GingerHead; 26.05.2015
comment
потому что на самом деле car не имеет столбца с именем car_owner_id . . . ничего не решено. . . - person GingerHead; 26.05.2015
comment
Я не уделял должного внимания SQL Ginger. Ну тогда это не двунаправленный. Это фундаментальный недостаток. - person Shahzeb; 26.05.2015
comment
У вас есть другое решение? - person GingerHead; 26.05.2015
comment
По сути, вам придется либо добавить этот столбец в базу данных, либо сделать его однонаправленным. Другой возможности нет. В базе данных Car знает о владельце. - person Shahzeb; 26.05.2015
comment
Но почему это работает, когда вторая таблица имеет внешний ключ к первой, а не наоборот, какая разница? - person GingerHead; 09.06.2015