jpa 有人能解释一下我在Hibernate中@MapsId吗?

5jdjgkvh  于 2022-11-14  发布在  其他
关注(0)|答案(5)|浏览(345)

有人能给我解释一下休眠中的@MapsId吗?我很难理解它。
如果能用一个例子来解释它,以及它在什么样的用例中最适用,那就太好了。

v8wbuo2f

v8wbuo2f1#

下面是Object DB的一个很好的解释。
指定ManyToOne或OneToOne关系属性,该属性提供EmbeddedId主键、EmbeddedId主键中的属性或父实体的简单主键的Map。value元素指定关系属性所对应的组合键中的属性。如果实体的主键与关系所引用的实体的主键的Java类型相同,未指定值属性。

// 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文档。

0sgqnhkj

0sgqnhkj2#

我发现这张便条也很有用:Hibernate注解中的@MapsId将一个列Map到另一个表的列。
它还可用于在两个表之间共享相同的主键。
示例:

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

camsedfj3#

恕我直言,考虑@MapsId的最佳方式是当您需要在n:m实体中Map组合键时。
例如,客户可以有一个或多个顾问,而顾问可以有一个或多个客户:

您的实体应该是这样的(伪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;
}

通过这种Map方式,每当保存顾问时,JPA都会自动在EmbeddableId中插入CustomerConsultant id,因此您不需要手动创建CustomerByConsultantPk

ehxuflar

ehxuflar4#

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

qyyhg6bp

qyyhg6bp5#

MapsId允许您在两个不同的实体/表之间使用相同的主键。当您使用MapsId时,CASCADE.ALL标志将变得无用,您将需要确保您的实体是手动保存的。

相关问题