Understanding @MapsId annotation in sleep mode

According to Hibernate documentation, the explanation for the annotation is @MapsId

stated as:

In the built-in id object, the association is represented as the identifier of the associated object. But you can tie your value to a regular association in essence through the @MapsId annotation. The @MapsId value matches the property name of the embedded identifier object that contains the corresponding object identifier. In a database, this means that the Customer.user and CustomerId.userId properties share the same base column (user_fk in this case).

@Entity
class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;

   @MapsId("userId")
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   })
   @OneToOne User user;
}

@Embeddable
class CustomerId implements Serializable {
   UserId userId;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;

   //implements equals and hashCode
}

      

He also says:

Not yet supported in JPA, Hibernate allows you to bind directly in the inline id component (instead of using the @MapsId annotation).

@Entity
class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;
}

@Embeddable
class CustomerId implements Serializable {
   @OneToOne
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   }) 
   User user;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;


   //implements equals and hashCode
}

      

I tried to create tables using Hibernate ( hbm2ddl.auto=create

) itself to understand how the annotation is used @MapsId

. Here are my observations:

If my object declaration for Customer

and User

looks like this:

@Entity
@Table(name="TBL_CUSTOMER")
public class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;

   @MapsId("userId")
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   })
   @OneToOne User user;
}

@Entity 
@Table(name="TBL_USER")
class User {
   @EmbeddedId UserId id;
   Integer age;
}

      

Then the DDL statements generated by Hibernate say:

Hibernate: create table TBL_CUSTOMER (customerNumber varchar2(255 char) not null, preferredCustomer number(1,0) not null, userfirstname_fk varchar2(255 char) not null, userlastname_fk varchar2(255 char) not null, primary key (customerNumber, userfirstname_fk, userlastname_fk))
Hibernate: create table TBL_USER (firstName varchar2(255 char) not null, lastName varchar2(255 char) not null, age number(10,0), primary key (firstName, lastName))
Hibernate: alter table TBL_CUSTOMER add constraint UK_chvh5mukc81xk9t6fis3skab  unique (userfirstname_fk, userlastname_fk)
Hibernate: alter table TBL_CUSTOMER add constraint FK_chvh5mukc81xk9t6fis3skab foreign key (userfirstname_fk, userlastname_fk) references TBL_USER

      

Now if I change my object Customer

to:

@Entity
@Table(name="TBL_CUSTOMER")
public class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;

   @OneToOne User user;
}

      

Then the DDL statements:

Hibernate: create table TBL_CUSTOMER (customerNumber varchar2(255 char) not null, firstName varchar2(255 char), lastName varchar2(255 char), preferredCustomer number(1,0) not null, user_firstName varchar2(255 char), user_lastName varchar2(255 char), primary key (customerNumber, firstName, lastName))
Hibernate: create table TBL_USER (firstName varchar2(255 char) not null, lastName varchar2(255 char) not null, age number(10,0), primary key (firstName, lastName))
Hibernate: alter table TBL_CUSTOMER add constraint FK_et3bgekef237d4kov7b9oqt85 foreign key (user_firstName, user_lastName) references TBL_USER

      

In this case, I see 2 extra columns (first and last name) for TBL_CUSTOMER

if I remove annotations @MapsId

and @JoinColumn

. Also, the additional command alter does not exist in this case.

I am new to Hibernate, so it is difficult for me to understand the explanation given in the Hibernate docs, what is the purpose @MapsId

, when should we use it and how it affects the underlying database schema.

Also I went through this SO post - can someone explain @MapsId to me in hibernation? but I can't get clear information about this annotation.

+4


source to share


1 answer


@MapsId is used to tell hibernate (or any JPA provider, actually) to use the same id of another entity with a 1: 1 relationship to this one.



This will avoid using an extra column to store the link between the two rights, while still allowing bi-directional communication.

0


source







All Articles