Почему мне нужна третья таблица для сопоставления "многие ко многим"? Почему я не могу просто использовать два стола?
Я 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.