如何使用链接表在Hibernate中映射多对多列表

时间:2008-12-22 23:49:41

标签: java hibernate mapping

我想使用链接表在Hibernate中映射多对多。我有两个类,父类和子类,例如:

public class Parent{

private List<Child> _children;

//...getters and setters
}

我使用包含三列link_idparent_idchild_id的链接表(link_table)。数据库是SQL Server,id类型是uniqueidentifier。所以,我通常使用guid作为id字段。

如果要使用正确的标记,如何使用 <list /> 标记实现此目标?你知道有什么好的文件来完成这个吗?

我目前正在收到ConstraintViolationException,但未能找到任何好的文档或示例。

我认为主要问题是:如何指定在链接表中自动生成的link_id

4 个答案:

答案 0 :(得分:8)

我使用注释来做,特别是@ManyToMany和@JoinTable:

Hibernate Docs:

@Entity
public class Employer implements Serializable {
    @ManyToMany(
        targetEntity=org.hibernate.test.metadata.manytomany.Employee.class,
        cascade={CascadeType.PERSIST, CascadeType.MERGE}
    )
    @JoinTable(
        name="EMPLOYER_EMPLOYEE",
        joinColumns=@JoinColumn(name="EMPER_ID"),
        inverseJoinColumns=@JoinColumn(name="EMPEE_ID")
    )
    public Collection getEmployees() {
        return employees;
    }
}


@Entity
public class Employee implements Serializable {
    @ManyToMany(
        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
        mappedBy = "employees",
        targetEntity = Employer.class
    )
    public Collection getEmployers() {
        return employers;
    }
}

答案 1 :(得分:5)

我认为不可能(或有必要)将link_id主键添加到连接表中。连接表通常由两个参与表的主键组成。

使用XML,你需要这样的语法:

 <class name="Parent">
    ....
    <list name="children" table="link_table">
    <key column="parent_id"/>
    <many-to-many column="child_id"
        class="Children"/>
    </list>
    ...
 </class>

<class name="Child">
...
<list name="parents" inverse="true" table="link_table">
    <key column="child_id"/>
    <many-to-many column="parent_id"
        class="Parent"/>
</list>
...
</class>

虽然我发现注释更好用。

答案 2 :(得分:0)

我不确定您是否可以轻松地将现有数据与现有数据相关联。在第一次连接时,Hibernate通常最好定义自己的数据模式...

我只使用注释来提取多对多,但我认为hibernate文档提供了基于XML的示例:link text

答案 3 :(得分:0)

我在网上发现了一个非常好的博客,它提供了两种方法来为多对多映射的hibernate列添加其他字段。 传统上,我们期望多对多的映射给出一个新的表,FK的表映射。但是有一些方法可以调整它并为此连接表添加更多字段/列。

此连接表可能包含PK或可能包含一些没有PK的额外字段。 请参阅此博客,了解具体实施情况See Here

根据您的示例,您需要在表中添加额外的PK,以便声明一个新表ParentChildren并将主键声明为l​​inkId。我只显示了已经上传的parentchildren类,因为父类和子类中的多对多映射的注释可以从上面的帖子中引用。

@Entity
@Table(name = "parent_children")
public class ParentChildren{
    @Id @GeneratedValue
    private long linkId;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id") 
    private Parent parent;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "children_id) 
    private Children children;

    // additional fields if you want
    private boolean activated;

    //getters and setters
    }
}

因此,这将创建一个映射表,其中linkId作为主键,parent_id和children_id作为外键。只需要明确为什么你需要将link_id作为主键分别以及如何使用它。