如何在hibernate中定义复合外键映射?

Posted

技术标签:

【中文标题】如何在hibernate中定义复合外键映射?【英文标题】:How to define composite foreign key mapping in hibernate? 【发布时间】:2021-12-12 13:35:51 【问题描述】:

我有两个表:users和userdetails如下:

package com.example.easynotes.model;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "users")
@IdClass(UserID.class)
public class User implements Serializable 

    @Id
    int id;

    @Id
    String name;

    String department;

    //getters and setters


userdetails 类是这样的:

public class UserDetails implements Serializable

int id;

String name;

String address;

String otherFields;

//getters and setters


users 中的 id 和 name 是复合主,我希望 userdetails 中的相同字段成为外键。如何在休眠中实现这一点?

【问题讨论】:

vladmihalcea.com/… 【参考方案1】:

我们需要将两个键都放入@Embeddable 以分离复合键,然后使用@EmbeddedId 将其放入User 实体中并使用Hibernate Relational Mapping 映射两个主键...

Composite Primary Key有两种选择:

    使用@EmbeddedId 使用@IdClass()

下面是例子:

---------------------- 使用 EmbeddedId -------- ----------------------------------------

复合主键:

@Embeddable
public class UserIdName implements Serializable 
    int id;
    String name;
    
    // getter and setter

用户:

@Entity
@Table(name = "users")
public class USER
    @EmbeddedId
    private UserIdName id;

    String department;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private Set<Userdetail> userdetail;

    // getter and setter

用户详情:

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

    @Id
    private int detail_id;

    @ManyToOne
    @JoinColumns( @JoinColumn(name = "id", referencedColumnName = "id"),
            @JoinColumn(name = "name", referencedColumnName = "name") )
    private USER user;

    String address;

    String otherFields;

    // getter setter

---------------------- 使用 IdClass -------- ----------------------------------------

复合主键:

public class UserIdName implements Serializable 
    int id;
    String name;
    
    // getter and setter

用户:

@Entity
@Table(name = "users")
@IdClass(UserIdName.class)
public class USER
    @Id
    int id;

    @Id
    String name;

    String department;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private Set<Userdetail> userdetail;

    // getter and setter

用户详情:

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

    @Id
    private int detail_id;

    @ManyToOne
    @JoinColumns( @JoinColumn(name = "id", referencedColumnName = "id"),
            @JoinColumn(name = "name", referencedColumnName = "name") )
    private USER user;

    String address;

    String otherFields;

    // getter setter

->如果您想手动插入两个外键,请尝试以下代码

将此代码放入UserDetails

@ManyToOne
@JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
@JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
private USER user;

@Column(name="id")
private int id;

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

// don't forget to put getter setter

用户表:

用户明细表:

【讨论】:

通过@IdClass 没有解决方案吗?你的这个解决方案在插入数据时也会保持约束吗? 如何在 userdetails 对象中设置 id 和 name ? 您要手动添加两个外键? 您有两个选项 @IdClass@EmbeddedId 用于复合键,请参阅上面编辑的答案

以上是关于如何在hibernate中定义复合外键映射?的主要内容,如果未能解决你的问题,请参考以下文章

hibernate5(12)注解映射[4]一对一外键关联

如何进行 Hibernate XML 映射,一对多使用 1 PK 映射到另一个具有复合键的实体

在 merge() 操作中丢失复合外键(JPA/Hibernate)

Hibernate:insertable = false,updatable = false 属于涉及外键的复合主键星座中的哪里?

将复合键映射到两个外键

休眠。如何将条目添加到具有来自 Hibernate 中 2 个不同表的 2 个外键的表中?