can someone please explain me @MapsId in hibernate?

后端 未结 5 1616
天涯浪人
天涯浪人 2020-11-29 03:34

Can someone please explain to me @MapsId in hibernate? I\'m having a hard time understanding it.

It would be great if one could explain it with an examp

相关标签:
5条回答
  • 2020-11-29 03:43

    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.

    0 讨论(0)
  • 2020-11-29 03:44

    Here is a nice explanation from Object DB.

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

    Read the API Docs here.

    0 讨论(0)
  • 2020-11-29 03:44

    As he explained Vladimir in his tutorial, The best way to map a @OneToOne relationship is to use @MapsId. This way, you don’t even need a bidirectional association since you can always fetch the Child entity by using the Parent entity identifier.

    0 讨论(0)
  • 2020-11-29 03:51

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

    It can be used also to share the same primary key between 2 tables.

    Example:

    @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;
        ...
    }
    
    0 讨论(0)
  • 2020-11-29 03:54

    IMHO, the best way to think about @MapsId is when you need to map a composite key in a n:m entity.

    For instance, a customer can have one or more consultant and a consultant can have one or more customer:

    And your entites would be something like this (pseudo Java code):

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

    Mapping this way, JPA automagically inserts Customer and Consultant ids in the EmbeddableId whenever you save a consultant. So you don't need to manually create the ConsultantByConsultantPk.

    0 讨论(0)
提交回复
热议问题