【问题标题】:How to use the Primary Key of one table as Primary Key of another using Hibernate如何使用 Hibernate 将一个表的主键用作另一个表的主键
【发布时间】:2022-01-22 00:59:00
【问题描述】:

使用 Hibernate,我创建了两个实体 - Employee 和 EmployeeDetails。由于 EmployeeDetails 不能在 Employee 中没有相应条目的情况下存在,所以我认为我不需要 EmployeeDetails 的额外 ID,而是可以使用 Employee 实体的 ID。以下是我实现这个想法的方式:

员工实体:

@Entity
@Table(name = "employees")
@Data
public class Employee {

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

    @Column(name = "first_name", nullable = false)
    private String firstName;
    @Column(name = "last_name", nullable = false)
    private String lastName;
    @OneToOne(cascade = CascadeType.ALL)
    EmployeeDetails employeeDetails;
}

员工详细信息实体:

@Entity
@Table(name = "employee_details")
@Data
public class EmployeeDetails {

    @Id
    private Long id;

    @Column(name = "address")
    private String address;
    @Column(name = "e_mail", nullable = false)
    private String eMail;
    @Column(name = "phone")
    private String phone;
    @MapsId
    @OneToOne(mappedBy = "employeeDetails", cascade = CascadeType.ALL)
    @JoinColumn(name = "employee_id")
    private Employee employee;
}

通过将 @MapsId 注释添加到 EmployeeDetails 中的员工变量,我应该将 Employee-entity 的主键分配给 EmployeeDetails 的 Id 列。

在第二步中,我已将一些数据写入我的两个表中。

MySQL 数据库中的员工表:

employee_id    first_name    last_name    employee_details_employee_id
1              John          Smith        null
2              Jennifer      Adams        null

最后一列是由 Hibernate 生成的。我不明白为什么。它似乎是一些用于识别的列,但我不需要它。

MySQL 数据库中的employee_details 表:

employee_id    address    e_mail                     phone
1              null       john.smith@gmail.com       null
2              null       jennifer.adams@gmail.com   null

我只给员工分配了一封电子邮件。令人惊讶的是,该数据库表中没有员工条目。反正我真的不需要它,但我期待它。所以,是的,我认为我做错了什么,非常感谢一些帮助。

【问题讨论】:

    标签: java mysql database hibernate spring-data-jpa


    【解决方案1】:

    改变mappedBy侧,这里有用的链接

    https://vladmihalcea.com/change-one-to-one-primary-key-column-jpa-hibernate/ https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/ https://javabydeveloper.com/one-one-bidirectional-association/

    @Entity
    @Table(name = "employees")
    @Data
    public class Employee {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Column(name = "first_name", nullable = false)
        private String firstName;
        @Column(name = "last_name", nullable = false)
        private String lastName;
        @OneToOne(mappedBy = "employee", cascade = CascadeType.ALL)
        EmployeeDetails employeeDetails;
    }
    
    Entity
    @Table(name = "employee_details")
    @Data
    public class EmployeeDetails {
    
        @Id
        private Long id;
        @Column(name = "address")
        private String address;
        @Column(name = "e_mail", nullable = false)
        private String eMail;
        @Column(name = "phone")
        private String phone;
        @MapsId
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "employee_id")
        private Employee employee;
    }
    

    【讨论】:

      【解决方案2】:

      @MapId 在使用 Hibernate 时不是一个流行的解决方案。 也许在您的情况下,@Embeddable 会是更好的选择?

      如果我理解正确,EmployeeDetails 不能在没有关联的Employee 的情况下存在。所以,EmployeeDetails 可以是 Employee 中的一个字段作为可嵌入字段:

      @Entity
      @Table(name = "employees")
      @Data
      public class Employee {
      
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          @Column(name = "employee_id")
          private Long id;
      
          @Column(name = "first_name", nullable = false)
          private String firstName;
          @Column(name = "last_name", nullable = false)
          private String lastName;
          
          @Embedded
          EmployeeDetails employeeDetails;
      }
      

      那么EmployeeDetails不需要ID和与员工的关系:

      @Embeddable
      public class EmployeeDetails {
      
          @Column(name = "address")
          private String address;
          @Column(name = "e_mail", nullable = false)
          private String eMail;
          @Column(name = "phone")
          private String phone;
      }
      

      如您所见,现在数据库中只有一张表employees,但在我们的休眠模型中,我们有两个分开的对象。可能没有Employee实体就不需要EmployeeDetails,这样构造效率更高。

      如果您确实需要与Employee 相关的EmployeeDetails 的分隔表,我建议创建标准的一对一映射而不是@MapId 构造。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 1970-01-01
        相关资源
        最近更新 更多