有人可以在休眠中向我解释@MapsId
吗?我很难理解它。
如果可以用一个例子来解释它会很好,它最适用于什么样的用例?
这是来自 Object DB 的一个很好的解释。
指定为 EmbeddedId 主键、EmbeddedId 主键中的属性或父实体的简单主键提供映射的 ManyToOne 或 OneToOne 关系属性。 value 元素指定关系属性对应的复合键中的属性。如果实体的主键与关系引用的实体的主键属于同一 Java 类型,则不指定 value 属性。
// parent entity has simple primary key
@Entity
public class Employee {
@Id long empId;
String name;
...
}
// dependent entity uses EmbeddedId for composite key
@Embeddable
public class DependentId {
String name;
long empid; // corresponds to primary key type of Employee
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
@MapsId("empid") // maps the empid attribute of embedded id
@ManyToOne Employee emp;
}
在此处阅读 API Docs。
我发现这个注释也很有用:休眠注释中的 @MapsId
将一个列映射到另一个表的列。
它还可以用于在 2 个表之间共享相同的主键。
例子:
@Entity
@Table(name = "TRANSACTION_CANCEL")
public class CancelledTransaction {
@Id
private Long id; // the value in this pk will be the same as the
// transaction line from transaction table to which
// this cancelled transaction is related
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_TRANSACTION", nullable = false)
@MapsId
private Transaction transaction;
....
}
@Entity
@Table(name = "TRANSACTION")
@SequenceGenerator(name = "SQ_TRAN_ID", sequenceName = "SQ_TRAN_ID")
public class Transaction {
@Id
@GeneratedValue(generator = "SQ_TRAN_ID", strategy = GenerationType.SEQUENCE)
@Column(name = "ID_TRANSACTION", nullable = false)
private Long id;
...
}
@MapsId
。它甚至有什么不同吗?
@Id
和 @GeneratedValue
和 @Column
的那个)并且与另一个表有一个 @OneToOne
和 @JoinColumn
,另一个表将有 @MapsId
。但是,如果您想先插入“其他表”,这可能行不通。
恕我直言,考虑 @MapsId
的最佳方式是当您需要在:m 实体中映射复合键时。
例如,一个客户可以有一个或多个顾问,而一个顾问可以有一个或多个客户:
https://i.stack.imgur.com/CUUE4.png
您的实体将是这样的(伪 Java 代码):
@Entity
public class Customer {
@Id
private Integer id;
private String name;
}
@Entity
public class Consultant {
@Id
private Integer id;
private String name;
@OneToMany
private List<CustomerByConsultant> customerByConsultants = new ArrayList<>();
public void add(CustomerByConsultant cbc) {
cbc.setConsultant(this);
this.customerByConsultant.add(cbc);
}
}
@Embeddable
public class CustomerByConsultantPk implements Serializable {
private Integer customerId;
private Integer consultantId;
}
@Entity
public class CustomerByConsultant{
@EmbeddedId
private CustomerByConsultantPk id = new CustomerByConsultantPk();
@MapsId("customerId")
@JoinColumn(insertable = false, updatable = false)
private Customer customer;
@MapsId("consultantId")
@JoinColumn(insertable = false, updatable = false)
private Consultant consultant;
}
通过这种方式映射,每当您保存顾问时,JPA 都会在 EmbeddableId
中自动插入 Customer
和 Consultant
id。因此您无需手动创建 CustomerByConsultantPk
。
MapsId 允许您在两个不同的实体/表之间使用相同的主键。注意:当您使用 MapsId 时,CASCADE.ALL
标志变得无用,您需要确保您的实体是手动保存的。
不定期副业成功案例分享
@MapsId
指定的列的实体将在持久层(数据库)中只有主键列。这个想法是在两个实体之间共享主键。Employee
的标识符就可以获取Dependent
。