为什么我需要第三个表进行多对多映射?为什么我不能只使用两张桌子?

时间:2013-06-25 08:32:10

标签: java hibernate many-to-many hibernate-mapping

我一直在尝试many to manyPerson两个班级之间的Address关系。我不知道,但在某个地方我并没有按照正确的方向思考。例如,对于多对多的映射,我制作了两个表

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

然后我在映射xml 中尝试了一些东西。在一些不成功的尝试之后,我读到你需要三个表来进行多对多的映射,就像answer我的一个问题所说的那样。

请解释一下原因?为什么我需要第三张桌子?为什么我不能仅仅与两个表建立关联?

4 个答案:

答案 0 :(得分:8)

第三个表用作定义多对多关系的联结表。在您的示例中,我假设Person可以包含多个addresses,并且地址可以属于多个People无法使用两个表格对此关系进行建模。

您可以尝试简单地将外键包含在Address表中的PersonPerson表中的Address的外键中。这些映射中的每一个都具有one侧,意味着特定实体的one对应于另一个的many。这些选项都不会达到many to many关系,并且需要使用第三个表来映射更复杂的关系。

为了映射为many to many,您需要能够将两个实体的多个实例相互关联。传统上通过以下方式完成:

Table A
ID_A

Table B
ID_B

Table C
ID_A
ID_B

答案 1 :(得分:6)

由于关系的性质。

如果映射一对一,则可以向person_id表添加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相关!因此,您需要第三个表来关联所有PersonAddress 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 | 
+---------+

答案 2 :(得分:2)

嗯,我不确定,但我认为他正在谈论创造一个"第三类"在他的映射中而不是真正的第三个表#34; (否则他甚至不会谈论hibernate映射)。因此,我将假设他正在努力解决我的答案(并且以后对于他的hibernate映射仍然有用):

感谢@JoinTable注释,您不必为第三个表创建实体。如果你的表之间有多对多的关系,你只需创建2个实体" Person"和#34;地址"以及每一方的@JoinTable注释将应用多对多魔术而无需为它们之间的第三个表创建实体。

除非你的第三张表有一些额外的列,然后在那种情况下你没有选择,你将不得不为这第三个表创建一个特定的实体(或者你不能得到它只有" Person"和"地址"实体的额外列。

您的映射的一些有用链接:

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/

答案 3 :(得分:0)

我使用ManyToMany和JPA注释,我需要你宝贵的建议。 (假设人和地址。相同地址被称为更多人(住在同一地址))。我必须从该地址删除一个人。

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

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

对两个人使用相同的添加引用。做得好

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

在合并或持续时,iit映射得恰当。

p1 - add1   p2 - add1

当我做

时,我必须单独删除p2
p2.removeAddress(add1)
    removeAddress(add1) { coll.remove(add1) }

它会删除地址条目,并且Hibernate jpa提供程序再次尝试在Address实体上保留并且说“已删除的实体已传递给持久化”并且henc事务回滚发生。    

我正在捣蛋
@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.