Hibernate: внешний ключ имеет неправильный номер столбца. должно быть 0 - PullRequest
3 голосов
/ 06 сентября 2010

Я пытаюсь оценить отображение в этом документе Hibernate: раздел 2.2.3.1. Генерация идентификатора свойства

http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-mapping-identifier

В документе Person и MedicalHistory имеет отображение @OneToOne (MedicalHistory указывает на Person), и документ предлагает две стратегии отображения:

Первая стратегия:

@Entity
class MedicalHistory implements Serializable {
  @Id @OneToOne
  @JoinColumn(name = "person_id")
  Person patient;
}

@Entity
public class Person implements Serializable {
  @Id @GeneratedValue Integer id;
}

Вторая стратегия:

@Entity
class MedicalHistory implements Serializable {
  @Id Integer id;

  @MapsId @OneToOne
  @JoinColumn(name = "patient_id")
  Person patient;
}

@Entity
class Person {
  @Id @GeneratedValue Integer id;
}

Теперь все работает нормально, но ...

Чтобы усложнить ситуацию, я добавляю еще одну (3-ю) таблицу (класс), которая имеет отношение @ManyToOne к MedicalHistory. И первая стратегия потерпит неудачу (пока 2-я стратегия все еще работает).

Я создаю еще один (третий) класс с именем MedicalLog, который имеет отношение @ManyToOne к MedicalHistory:

@Entity
public class MedicalLog implements Serializable
{
  @Id @GeneratedValue
  private int id;

  @ManyToOne
  @JoinColumn(name="MedicalHistory_id")
  private MedicalHistory medicalHistory;

  private String action;      
  private Timestamp time;

  public MedicalLog(MedicalHistory mh , String action)
  {
    this.medicalHistory = mh;
    this.action = action;
  }
  // other methods
}

Исключение возникает при инициализации hibernate ...:

Caused by: org.hibernate.AnnotationException: A Foreign key refering destiny.play.MedicalHistory from destiny.play.MedicalLog has the wrong number of column. should be 0
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:421)
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:111)

Лично я люблю стратегию 1 больше, потому что она не вводит другую переменную Integer id . И я чувствую, что Object id (стратегия 2) более удобен (стиль OO).

В любом случае, хотя стратегия 2 работает, но мне интересно, есть ли способ заставить стратегию 1 также работать?

Большое спасибо!

- обновлено: создание таблицы -

Создание таблицы (MySQL):

CREATE TABLE IF NOT EXISTS `Person` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `MedicalHistory` (
  `patient_id` int(10) NOT NULL,
  PRIMARY KEY (`patient_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `MedicalLog` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `MedicalHistory_id` int(10) NOT NULL,
  `action` varchar(15) NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Надеюсь, это поможет

1 Ответ

1 голос
/ 07 сентября 2010

Исключение возникает при инициализации спящего режима ...

Какую версию Hibernate EntityManager вы используете? Я не смог воспроизвести проблему с 3.5.5-Final и той же аннотированной объектной моделью (стратегией первых) в моем любимом проекте.

Созданы следующие таблицы:

create table MedicalHistory (person_id integer not null, primary key (person_id), unique (person_id))    
create table MedicalLog (id integer generated by default as identity, action varchar(255), time timestamp, MedicalHistory_id integer, primary key (id))    
create table Person (id integer generated by default as identity, dept varchar(255), firstName varchar(255), gender varchar(255), lastName varchar(255), primary key (id))    
alter table MedicalHistory add constraint FK306558E319ACB65E foreign key (person_id) references Person    
alter table MedicalLog add constraint FKEDF39713FC40377E foreign key (MedicalHistory_id) references MedicalHistory

И Hibernate инициализируется без нареканий.

...