根据 Hibernate documentation , @MapsId
注解的解释如下:
In the embedded id object, the association is represented as the identifier of the associated entity. But you can link its value to a regular association in the entity via the @MapsId annotation. The @MapsId value correspond to the property name of the embedded id object containing the associated entity's identifier. In the database, it means that the Customer.user and the CustomerId.userId properties share the same underlying 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
}
还说:
While not supported in JPA, Hibernate lets you place your association directly in the embedded id component (instead of having to use 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
}
我尝试使用 Hibernate 本身 (hbm2ddl.auto=create
) 生成表格,以了解如何使用 @MapsId
注释。以下是我的观察:
如果我的 Customer
和 User
实体声明如下:
@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;
}
然后 Hibernate 生成的 DDL 语句说:
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
现在,如果我将我的 Customer
实体更改为:
@Entity
@Table(name="TBL_CUSTOMER")
public class Customer {
@EmbeddedId CustomerId id;
boolean preferredCustomer;
@OneToOne User user;
}
那么DDL语句是:
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
在这种情况下,如果我删除 @MapsId
和 @JoinColumn
注释,我会看到 TBL_CUSTOMER
有 2 个额外的列(名字和姓氏)。在这种情况下也没有额外的 alter 命令。
我是 Hibernate 的新手,所以我发现很难理解 Hibernate 文档中给出的解释,@MapsId
的目的是什么,我们何时必须使用它以及它如何影响底层数据库架构。
我也看过这篇 SO 帖子 - can someone please explain me @MapsId in hibernate?但我无法获得有关此注释的明确信息。
最佳答案
@MapsId 用于告诉 hibernate(或任何 JPA 提供程序,实际上)使用与此实体具有一对一关系的另一个实体的相同 ID。
这将避免使用额外的列来存储两个实体之间的引用,同时能够拥有双向关系。
关于java - 理解 Hibernate 中的 @MapsId 注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25236449/