如何使用 Hibernate 注释标记外键约束?

Posted

技术标签:

【中文标题】如何使用 Hibernate 注释标记外键约束?【英文标题】:How can I mark a foreign key constraint using Hibernate annotations? 【发布时间】:2013-03-03 19:59:21 【问题描述】:

我正在尝试使用 Hibernate 注释为我的数据库表编写模型类。

我有两个表,每个表都有一个主键 User 和 Question。

@Entity
@Table(name="USER")
public class User

    @Id
    @Column(name="user_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name="username")
    private String username;

    // Getter and setter

问题表。

@Entity
@Table(name="QUESTION")
public class Questions extends BaseEntity

    @Id
    @Column(name="question_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @Column(name="question_text")
    private String question_text;

    // Getter and setter

我还有一个表 UserAnswer,它有 userId 和 questionId 作为上述两个表的外键。

但我无法找到如何在 UserAnswer 表中引用这些约束。

@Entity
@Table(name="UserAnswer ")
public class UserAnswer

    @Column(name="user_id")
    private User user;

    //@ManyToMany
    @Column(name="question_id")
    private Questions questions ;

    @Column(name="response")
    private String response;

    // Getter and setter

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

@Column 不是合适的注释。您不想将整个用户或问题存储在列中。您想要在实体之间创建关联。首先将Questions 重命名为Question,因为一个实例代表一个问题,而不是多个问题。然后创建关联:

@Entity
@Table(name = "UserAnswer")
public class UserAnswer 

    // this entity needs an ID:
    @Id
    @Column(name="useranswer_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "question_id")
    private Question question;

    @Column(name = "response")
    private String response;

    //getter and setter 

Hibernate documentation 解释了这一点。阅读。并阅读注释的javadoc。

【讨论】:

非常感谢您的回复。是否需要在表中创建一个新列作为 useranswer_id ?如果我可以将其他两个 id 作为复合键,是否有可能? 这是可能的,但它的设计很糟糕、痛苦、难以使用且效率低下。做正确的事,并为您的所有实体分配一个自动生成的单列 ID。 @JB_Nizet 我不介意向实体添加 id 列。但是我还需要在表中添加一列吗?我的意思是 oracle 数据库。 是的,当然。如果对应的列不存在,Hibernate 会将实体的 ID 存储在哪里? 我问了我的团队负责人。我无法添加列。我必须使它们成为复合键。我尝试使用 @ EmbeddedId 和 @ Embeddable 。但我得到一个休眠异常【参考方案2】:

有很多答案,而且都是正确的。但不幸的是,他们都没有一个明确的解释。

以下内容也适用于非主键映射。

假设我们有第 1 列的父表 A 另一个表 B,第 2 列引用第 1 列:

@ManyToOne
@JoinColumn(name = "TableBColumn", referencedColumnName = "TableAColumn")
private TableA session_UserName;

@ManyToOne
@JoinColumn(name = "bok_aut_id", referencedColumnName = "aut_id")
private Author bok_aut_id;

【讨论】:

谢谢,这真的很有说明性。【参考方案3】:

@JoinColumn(name="reference_column_name") 注释可用于从其他实体引用的类的属性或字段之上。

【讨论】:

以上是关于如何使用 Hibernate 注释标记外键约束?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 无法添加外键约束

Mysql创建索引而不是外键约束

使用带有 Hibernate 的 JPA 注释来描述外键仅在子表中的 @OneToMany 关系

hibernate表关系

使用带有外键约束的 JPA 删除对象

如何使Doctrine PostgreSQL外键约束DEFERRABLE