Как иметь 2 коллекции одного типа в JPA? - PullRequest
15 голосов
/ 21 марта 2009

У меня есть 2 сущности в JPA: запись и комментарий. Запись содержит две коллекции объектов Comment.

@Entity
public class Entry {
    ...

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @IndexColumn(base = 1, name = "dnr")
    private List<Comment> descriptionComments = new ArrayList<Comment>();

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @IndexColumn(base = 1, name = "pmnr")
    private List<Comment> postMortemComments = new ArrayList<Comment>();

    ...
}

Для хранения таких объектов JPA + Hibernate создает таблицу «Entry», таблицу «Comment» и SINGLE «Entry_Comment»:

create table Entry_Comment (Entry_id integer not null, postMortemComments_id integer not null, pmnr integer not null, descriptionComments_id integer not null, dnr integer not null, primary key (Entry_id, dnr), unique (descriptionComments_id), unique (postMortemComments_id))

Ошибка сохранения объектов, поскольку descriptionComments_id и postMortemComments_id не могут быть "не нулевыми" одновременно.

Как сохранить объект, содержащий две коллекции одного типа, с использованием JPA + Hibernate?

Ответы [ 4 ]

13 голосов
/ 03 июля 2009

Это одна из многих ошибок Hibernate (точнее, HHH-3410 ).

Мне удалось это исправить, добавив @JoinTable аннотации к @OneToMany отношениям, каждое из которых имеет свое собственное имя таблицы.

В вашем случае это будет выглядеть так:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name="entity_descriptioncomments")
@IndexColumn(base = 1, name = "dnr")
private List<Comment> descriptionComments = new ArrayList<Comment>();

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name="entity_postmortemcomments")
@IndexColumn(base = 1, name = "pmnr")
private List<Comment> postMortemComments = new ArrayList<Comment>();

Примечание : необходимо также добавить аннотацию @IndexColumn (из-за другой проблемы Hibernate с несколькими пакетами EAGER: HHH-1718 / EJB-346 ).

4 голосов
/ 22 марта 2009

Для хранения 2 таких коллекций в JPA с DataNucleus (http://www.datanucleus.org) вы бы поступили точно так же, как вы сделали. У вас нет примечания @JoinTable, поэтому следует поместить FK в Comment для каждой из коллекций. Если у вас действительно есть @JoinTable где-то (или эквивалент XML), тогда установка имен соответствующих таблиц объединения (по одной для каждой коллекции) также будет работать (поэтому у них есть своя собственная таблица соединения) Совместное использование двух таблиц объединения возможно и в DataNucleus, но это не стандартная JPA, а расширение производителя.

Как это отображается в Hibernate, я понятия не имею, но тогда это JPA, так что должно быть согласованным, так как в этом смысл иметь спецификацию; -)

2 голосов
/ 22 марта 2009

Существует недостаток в текущем отображении с точки зрения модели данных / модели предметной области: на самом деле у вас есть single @ OneToMany отношения между Entry и Комментарий . И Комментарий сущность должна иметь еще один атрибут с именем type , который принимает 2 значения: ' description ' или ' postMortem '.

Чтобы соответствовать текущей реализации Entry сущности, вы можете рассмотреть возможность разбиения Comment сущности на 2 разных сущности (возможно, с использованием функций наследования JPA) и использования @ JoinTable аннотация в Запись .

0 голосов
/ 23 марта 2009

Если все, что вас волнует, это порядок, как насчет того, чтобы настроить два определения столбцов индекса на одно и то же имя?

...