JPA — проблема OneToMany, ManyToOne, OneToOne

Учитывая следующие две сущности:

class Parent {
       @OneToMany(cascade=CascadeType.ALL)
       private Set<Child> children;

       (...)
}


class Child {
       @ManyToOne
       private Parent parent;

       (...)
}

Я хотел бы две таблицы в базе данных. Один стол для родителей, другой для детей. Но Hibernate создает три таблицы: одну для родителей, одну для детей и одну для их присоединения (таблица с двумя полями).

Даже если я поставлю @OneToOne в родительский атрибут в дочернем классе, я все равно получу тот же результат.

Что мне не хватает?


person Stephan    schedule 04.08.2011    source источник


Ответы (3)


Атрибут mappedBy="parent" в аннотации отсутствует для построения двунаправленной связи.

class Parent {
   @OneToMany(mappedBy="parent",cascade=CascadeType.ALL)
   private Set<Child> children;

   (...)
}

class Child {
   @ManyToOne
   private Parent parent;

   (...)
}
person imotai    schedule 04.08.2011
comment
Что делать, если у вас есть Person OneToMany Items, и элемент может принадлежать только одному человеку. Будет ли элемент иметь ManyToOne или OneToOne? Мне кажется, что это должен быть OneToOne, теперь есть ребенок (учитывая, что у вас может быть только один родитель) - person mmm; 29.07.2017

Добавьте свойство mappedBy к @OneToMany в классе Parent. Это делает Child стороной-владельцем.

В Child добавьте аннотацию @JoinColumn к полю parent, чтобы объявить имя столбца внешнего ключа в дочерней таблице.

Из JavaDoc на @OneToMany#mappedBy:

Поле, которому принадлежит отношение. Требуется, если связь не является однонаправленной.

Для однонаправленных отношений нужна таблица соединений, но в вашем случае она двунаправленная, поэтому она необходима.

person Thomas    schedule 04.08.2011
comment
Hibernate автоматически генерирует правильный FK для меня: parent_id. Важно ли использовать JoinColumn ? - person Stephan; 04.08.2011
comment
@ Стефан, нет, вам не нужно использовать @JoinColumn, если сгенерированный столбец вам подходит. - person Thomas; 04.08.2011

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

@OneToMany(mappedBy="parent")
private Set<Child> children;

а также

@ManyToOne
@JoinColumn(name="parent_id")
private Parent parent;
person rompetroll    schedule 04.08.2011
comment
хорошо иметь это. hibernate не знает об ограничениях внешнего ключа. поэтому hibernate может только догадываться (использовать предположения шаблона имени), какой столбец используется для этого отношения. поэтому хорошо быть явным. - person rompetroll; 04.08.2011