Сопоставление двунаправленной связи JPA @ManyToOne с более чем одной таблицей с использованием таблиц соединения

Новое в JPA и ORM, так что этот вопрос может быть старым. У меня есть следующие таблицы:

CREATE TABLE INSTITUTION (
    inst_id BIGINT PRIMARY KEY,
    :
    :
);

и

CREATE TABLE PERSON (
    pers_id BIGINT PRIMARY KEY,
    :
    :
);

каждая из приведенных выше таблиц имеет отношение «один ко многим» к другой таблице, CONTACTINFO

CREATE TABLE CONTACTINFO (
    cont_id BIGINT PRIMARY KEY,
    :
    :
);

В таблицах СУБД связь может быть отображена с помощью двух таблиц соединения:

JOIN_CONTACTS_PERSON ( cont_id, pers_id )
JOIN_CONTACTS_INSTITUTION ( cont_id, inst_id )

В SQL связь может быть установлена ​​путем объединения нужных таблиц с использованием правильной таблицы соединения, например:

SELECT *
  FROM Person AS p
  JOIN Join_Contacts_Person AS jt ON p.pers_id = jt.pers_id
  JOIN Contacts AS c ON jt.cont_id = c.cont_id;

В JPA сторона-владелец отношения «один ко многим» должна быть стороной «многие», в данном случае это таблица «Контакты». Но, похоже, нет никакого способа сопоставить более одной таблицы соединений со стороны «многих», используя аннотации JPA.

Мои вопросы: 1) невозможно ли сопоставить двунаправленную ассоциацию «многие к одному» через более чем одну таблицу соединений? ... 2) Нельзя ли также сопоставить однонаправленное отношение «многие к одному» через две или более таблиц соединений? ... и ... 3) будет ли возможным обходным путем использовать аннотацию @ManyToMany для двух однонаправленных сопоставлений и сделать "одну" сторону владеющей стороной каждого отношения?


person scottb    schedule 15.08.2015    source источник


Ответы (1)


Но, похоже, нет никакого способа сопоставить более одной таблицы соединений со стороны «многих», используя аннотации JPA.

У вас тут неправильное представление. Кажется, вы думаете, что существует одна ассоциация ManyToOne, и вы хотели бы сопоставить ее с несколькими таблицами соединений. Это не так. Здесь у вас есть две разные ассоциации, и каждая из них имеет свою собственную таблицу соединений:

  1. у одного человека много контактов, и это отображается с помощью таблицы соединений между контактом и человеком
  2. одно учреждение имеет много контактов, и это отображается с помощью таблицы соединений между учреждением и человеком

Таким образом, ваш контактный объект будет выглядеть следующим образом:

@Entity
public class Contact
    @Id
    private Long id;

    @ManyToOne
    @JoinTable(name = "JOIN_CONTACTS_PERSON", 
               joinColumns=
                   @JoinColumn(name="CONT_ID"),
               inverseJoinColumns=
                   @JoinColumn(name="PERS_ID"))
    private Person owningPerson;

    @ManyToOne
    @JoinTable(name = "JOIN_CONTACTS_INSTITUTION", 
               joinColumns=
                   @JoinColumn(name="CONT_ID"),
               inverseJoinColumns=
                   @JoinColumn(name="INST_ID"))
    private Institution owningInstitution;

    // ...
}
person JB Nizet    schedule 15.08.2015
comment
Заблуждение, действительно. Большое спасибо за разъяснения. - person scottb; 15.08.2015