如何使用一个 table 的主键作为另一个使用 Hibernate 的主键
How to use the Primary Key of one table as Primary Key of another using Hibernate
我使用 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;
}
通过向 EmployeeDetails 中的员工变量添加 @MapsId
注释,我应该将 Employee 实体的主键分配给 EmployeeDetails 的 Id 列。
第二步,我将一些数据写入了我的两个 tables。
MySQL 数据库中的员工 table:
employee_id first_name last_name employee_details_employee_id
1 John Smith null
2 Jennifer Adams null
最后一列是由 Hibernate 以某种方式生成的。我不明白为什么。好像是什么识别栏,我不需要
employee_details table 在 MySQL 数据库中:
employee_id address e_mail phone
1 null john.smith@gmail.com null
2 null jennifer.adams@gmail.com null
我只给员工分配了一封电子邮件。令人惊讶的是,此数据库中没有员工条目 table。反正我真的不需要它,但我期待它。所以,是的,我认为我做错了一些事情,非常感谢您的帮助。
@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;
}
如您所见,现在在数据库中它只有一个 table employees
,但在我们的休眠模型中,我们有两个分离的对象。可能你不需要 EmployeeDetails
没有 Employee
实体,所以有更有效的构造。
如果您真的需要 EmployeeDetails
与 Employee
的分离 table,我建议创建标准的一对一映射而不是 @MapId
构造。
改变mappedBy side,这里是有用的链接
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;
}
我使用 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;
}
通过向 EmployeeDetails 中的员工变量添加 @MapsId
注释,我应该将 Employee 实体的主键分配给 EmployeeDetails 的 Id 列。
第二步,我将一些数据写入了我的两个 tables。
MySQL 数据库中的员工 table:
employee_id first_name last_name employee_details_employee_id
1 John Smith null
2 Jennifer Adams null
最后一列是由 Hibernate 以某种方式生成的。我不明白为什么。好像是什么识别栏,我不需要
employee_details table 在 MySQL 数据库中:
employee_id address e_mail phone
1 null john.smith@gmail.com null
2 null jennifer.adams@gmail.com null
我只给员工分配了一封电子邮件。令人惊讶的是,此数据库中没有员工条目 table。反正我真的不需要它,但我期待它。所以,是的,我认为我做错了一些事情,非常感谢您的帮助。
@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;
}
如您所见,现在在数据库中它只有一个 table employees
,但在我们的休眠模型中,我们有两个分离的对象。可能你不需要 EmployeeDetails
没有 Employee
实体,所以有更有效的构造。
如果您真的需要 EmployeeDetails
与 Employee
的分离 table,我建议创建标准的一对一映射而不是 @MapId
构造。
改变mappedBy side,这里是有用的链接
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;
}