有人可以在hibernate中解释我@MapsId吗?

时间:2012-03-29 10:34:10

标签: java hibernate jpa annotations hibernate-annotations

有人可以在hibernate中解释我@MapsId吗?我很难理解它。

如果能用一个例子解释它并且在哪种用例中它最适用,那会很棒吗?

5 个答案:

答案 0 :(得分:33)

以下是Object DB的一个很好的解释。

  

指定ManyToOne或OneToOne关系属性,该属性提供EmbeddedId主键,EmbeddedId主键中的属性或父实体的简单主键的映射。 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

答案 1 :(得分:11)

我发现这个注释也很有用:hibernate注释中的@MapsId将列与另一个表的列相映射。

它也可用于在两个表之间共享相同的主键。

示例:

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

恕我直言,思考@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 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就会在Customer中自动插入ConsultantEmbeddableId id。因此,您无需手动创建ConsultantByConsultantPk

答案 4 :(得分:0)

正如他在tutorial中向弗拉基米尔(Vladimir)解释的那样,映射@OneToOne关系的最佳方法是使用@MapsId。这样,您甚至不需要双向关联,因为您始终可以通过使用父实体标识符来获取子实体。