Почему мне нужна третья таблица для сопоставления "многие ко многим"? Почему я не могу просто использовать два стола?

Я many to many связь между двумя классами Person и Address. Я не знаю, но где-то я не думаю в правильном направлении. Например, для многих ко многим отображениям я сделал две таблицы

CREATE TABLE person(p_id INTEGER,p_name TEXT,PRIMARY KEY(p_id));
CREATE TABLE address(a_id INTEGER,address TEXT);

а потом я попробовал что-то в отображение xml. После некоторых неудачных попыток я прочитал, что вам нужно три таблицы для многих ко многим сопоставлениям, как ответ на один из моих вопросов говорит.

пожалуйста объясните мне причину этого ? Зачем мне третий стол ? Почему я не могу создать ассоциацию только с двумя таблицами ?

4 ответов


третья таблица служит в качестве таблицы соединений, которая определяет отношение многие ко многим. В вашем примере я предполагаю, что A Person может иметь несколько addresses и адрес может принадлежать нескольким People. это отношение нельзя смоделировать с помощью двух таблиц.

вы можете попытаться просто включить внешний ключ к Address на Person таблица или внешний ключ к Person на Address таблица. Каждое из этих отображений будет иметь one сторону, смысл one конкретных сущностей соответствует many другие. Ни один из этих вариантов не достигает many to many связь и использование третьей таблицы требуется для сопоставления более сложных отношений.

для того, чтобы отобразить как many to many вы должны иметь возможность связывать несколько экземпляров обеих сущностей друг с другом. Это традиционно делается с помощью следующего:

Table A
ID_A

Table B
ID_B

Table C
ID_A
ID_B

из-за природы отношения.

если отображение один на один, чем вы могли бы добавить до Address таблица и каждый Address Кортеж будет указывать только один Person.

 Address
+---------------------+
|id|p_id|address      |
+---------------------+
| 1|  1 |some street 1| //one address uniquely points to one person
+---------------------+
| 2|  2 |new street 5 | 
+---------------------+

же один-ко-многим: если Person может иметь несколько Addresses, тогда было бы несколько кортежей в Address таблица с теми же person_id.

 Address
+---------------------+
|id|p_id|address      |
+---------------------+
| 1|  1 |some street 1| //two addresses point to one person
+---------------------+
| 2|  1 |new street 5 | 
+---------------------+

но что, если один Person может быть нескольких Address es, но и один Address может принадлежать к нескольким Persons? Затем одна колонка person_id на Address таблица не будет достаточно, потому что один Address может относиться ко многим Persons! Таким образом, вам нужна третья таблица, чтобы связать все пары Persons и Addresses.

 Assoc table
+---------+
|a_id|p_id|    
+---------+
| 1  |  1 | //one address for two persons
+---------+
| 1  |  2 | 
+---------+
| 2  |  3 | //two addresses for the same person
+---------+
| 3  |  3 | 
+---------+

хммм, я не уверен, но я думаю, что он говорит о создании "третьего класса" в своем отображении, а не о "третьей таблице" (иначе он даже не говорил бы о отображении спящего режима). Поэтому я предположу, что он просто борется со своим отображением для моего ответа (и это все равно будет полезно позже для его отображения hibernate):

благодаря аннотации @JoinTable вам не нужно создавать объект для третьей таблицы. Если у вас есть многие-ко-многим между таблицами, вы просто нужно создать 2 сущности "Person" и "Address", и аннотация @JoinTable с каждой стороны будет применять магию "многие ко многим" без необходимости создавать сущность для третьей таблицы между ними.

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

некоторые полезные ссылки для вашего отображения:

http://www.mkyong.com/hibernate/hibernate-many-to-many-relationship-example-annotation/ http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/


Im, используя ManyToMany с аннотацией JPA, мне нужны ваши ценные предложения. (Предположим, лицо и адрес. Один и тот же адрес относится к большему числу лиц (проживающих по одному и тому же адресу)). Я должен удалить человека с этого адреса.

 Person p1 = new Person();
  Person p2 = new Person();
    Address add1 = new Address();

  p1.add(add1);
  p2.add(add1);

используя то же самое, добавьте ref к обоим лицам. Как хорошо делать

add1.add(p1)  ;
  add1.add(p2)  ;

затем при слиянии или сохранении IIT сопоставляется соответствующим образом.

Р1 - добавьте 1 Р2 - добавьте 1

Я должен удалить p2 в одиночку, когда я это сделал

p2.removeAddress(add1)
    removeAddress(add1) { coll.remove(add1) }

что происходит, он удалил запись для адреса и снова провайдером JPA Hibernate снова пытается сохраниться в сущности адреса и говорит, что "удаленная сущность передана для сохранения", и происходит откат транзакции henc. Я был ving maping как

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "XXXX", joinColumns = { @JoinColumn(name = "X1_ID", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "X2_ID", nullable = false, updatable = false) })
    private Collection<Parser> parsers;


    Please share your ideas.