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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/387806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:07:02  来源:igfitidea点击:

How to map many-to-many List in Hibernate with a Link Table

javahibernatemapping

提问by Brandon

I would like to map a many-to-many in Hibernate using a link table. I have two classes, Parent and Child class, for example:

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

public class Parent{

private List<Child> _children;

//...getters and setters
}

I use a link table (link_table) with three columns link_id, parent_id, and child_id. The database is SQL server and id types are uniqueidentifier. So, I usually use guid for the id fields.

我用三列的链接表(link_table) link_idparent_idchild_id。数据库是 SQL 服务器,id 类型是 uniqueidentifier。所以,我通常将 guid 用于 id 字段。

How can you implement this using the <list />tag if this is the correct tag to use? Do you know of any good documentation to accomplish this?

<list />如果这是要使用的正确标签,您如何使用标签实现这一点?你知道有什么好的文档来完成这个吗?

I am currently getting a ConstraintViolationException but have not been able to find any good documentation or examples of this.

我目前收到 ConstraintViolationException,但找不到任何好的文档或示例。

I think a main issue is: how to specify the link_idto be automatically generated in the link table.

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

采纳答案by Vincent Ramdhanie

I don't think that it is possible (or necessary) to add a link_id primary key to the join table. The join table will usually consist of the primary keys of the two participating tables.

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

Using XML you will need syntax like this:

使用 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>

Although I find annotations better to use.

虽然我发现注释更好用。

回答by Uri

I am not sure that you can pull this off easily for an existing database with existing data. Hibernate is usually better off defining its own data schema the first time you connect...

我不确定您是否可以为具有现有数据的现有数据库轻松实现这一点。Hibernate 通常最好在您第一次连接时定义自己的数据模式...

I've only pulled off many-to-many with annotations, but I think the hibernate documentation offers XML based examples: link text

我只使用注释实现了多对多,但我认为 hibernate 文档提供了基于 XML 的示例:链接文本

回答by Matt Lewis

I do this using annotations, specifically @ManyToMany and @JoinTable:

我使用注释来做到这一点,特别是@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;
    }
}

回答by himani1349

I found a very good blog online which gives 2 ways to add additional fields to the many to many mapped hibernate column. Traditionally we expect the many to many mapping to give a new table will FK's of tables mapped. But there are ways to tweak that and add more fields/column to this joined table.

我在网上找到了一个非常好的博客,它提供了 2 种向多对多映射的休眠列添加附加字段的方法。传统上我们期望多对多映射给一个新表将 FK 的表映射。但是有一些方法可以调整它并向这个连接的表添加更多的字段/列。

This joined table may contain a PK or may contain some extra fields without PK. See this blog for exact implementation See Here

这个连接表可能包含一个 PK 或者可能包含一些没有 PK 的额外字段。请参阅此博客以了解确切实施请参阅此处

And as per your example, you need an extra PK in the table so you declare a new table ParentChildren and declare your primary key as linkId. I am showing just the annoated parentchildren class, as annotations for many to many mapping in parent and children class can be referenced from post above.

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

@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
    }
}

So this will create a mapping table which has linkId as primary key and parent_id and children_id as Foreign Key. Just be clear on why you want a link_id separately as primary key and how you are going to use it.

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