Почему мне нужна третья таблица для сопоставления "многие ко многим"? Почему я не могу просто использовать два стола?
Я 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
может иметь несколько Address
es, тогда было бы несколько кортежей в 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
может принадлежать к нескольким Person
s? Затем одна колонка person_id
на Address
таблица не будет достаточно, потому что один Address
может относиться ко многим Person
s! Таким образом, вам нужна третья таблица, чтобы связать все пары Person
s и Address
es.
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.