谁能给我解释一下@MapsId 的冬眠状态?

有人能给我解释一下冬眠时的 @MapsId吗? 我很难理解。

如果能够用一个例子来解释它,并且在什么样的用例中它是最适用的,那就太好了?

103662 次浏览

下面是来自 对象数据库的一个很好的解释。

Designates a ManyToOne or OneToOne relationship attribute that provides the mapping for an EmbeddedId primary key, an attribute within an EmbeddedId primary key, or a simple primary key of the parent entity. The value element specifies the attribute within a composite key to which the relationship attribute corresponds. If the entity's primary key is of the same Java type as the primary key of the entity referenced by the relationship, the value attribute is not specified.

// 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 文件

I found this note also useful: @MapsId in hibernate annotation maps a column with another table's column.

它还可以用来在两个表之间共享相同的主键。

例如:

@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;
...
}

正如他在他的 教程中解释的 Vladimir,映射 @OneToOne关系的最好方法是使用 @MapsId。这样,您甚至不需要双向关联,因为您总是可以通过使用 Parent 实体标识符来获取 Child 实体。

MapsId lets you use the same primary key between two different entities/tables. Note: when you use MapsId, the CASCADE.ALL flag becomes useless, and you will need to make sure that your entities are saved manually.

恕我直言,考虑 @MapsId的最佳方式是在需要映射 n: m 实体中的复合键时。

例如,一个客户可以有一个或多个顾问,而一个顾问可以有一个或多个客户:

enter image description here

实体类似于下面这样(伪 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中插入 CustomerConsultant id。所以不需要手动创建 CustomerByConsultantPk