有人可以@MapsId
在休眠状态下向我解释吗?我很难理解它。
如果可以举一个例子来解释它,那就最棒了,并且它在哪种用例中最适用?
Answers:
这是Object DB的一个很好的解释。
指定ManyToOne或OneToOne关系属性,该属性提供EmbeddedId主键,EmbeddedId主键内的属性或父实体的简单主键的映射。值元素指定关系属性所对应的组合键中的属性。如果实体的主键与关系所引用的实体的主键具有相同的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文档。
@MapsId
在持久性层(数据库)中具有由will指定的列的实体仅具有主键列。这个想法是在两个实体之间共享主键。
Dependent
只需知道的标识符即可获取Employee
。
我发现此注释也很有用:@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
。但是,如果您想先插入“其他表”,则可能无法使用。
正如他在教程中向Vladimir解释的那样,映射@OneToOne关系的最佳方法是使用@MapsId。这样,您甚至不需要双向关联,因为您始终可以通过使用父实体标识符来获取子实体。
通过MapsId,您可以在两个不同的实体/表之间使用相同的主键。注意:当您使用MapsId时,该CASCADE.ALL
标志将变得无用,并且需要确保手动保存了您的实体。
恕我直言,最好的考虑方法@MapsId
是何时需要在:m实体中映射组合键。
例如,一个客户可以有一个或多个顾问,而一个顾问可以有一个或多个顾客:
您的实体将是这样的(伪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 ConsultantByConsultantPk implements Serializable {
private Integer customerId;
private Integer consultantId;
}
@Entity
public class ConsultantByConsultant {
@EmbeddedId
private ConsultantByConsultantPk id = new ConsultantByConsultantPk();
@MapsId("customerId")
@JoinColumn(insertable = false, updatable = false)
Customer customer;
@MapsId("consultantId")
@JoinColumn(insertable = false, updatable = false)
Consultant consultant;
}
通过这种方式映射,只要您保存顾问,JPA就会自动在其中插入IDCustomer
和Consultant
ID EmbeddableId
。因此,您无需手动创建ConsultantByConsultantPk
。