【问题标题】:Understanding @MapsId annotation in Hibernate理解 Hibernate 中的 @MapsId 注解
【发布时间】:2014-10-03 21:04:58
【问题描述】:

根据Hibernate documentation@MapsId注解的解释如下:

在嵌入的 id 对象中,关联表示为 关联实体的标识符。但是您可以将其值链接到 通过 @MapsId 注释在实体中进行常规关联。这 @MapsId 值对应嵌入​​id的属性名 包含关联实体标识符的对象。在数据库中, 这意味着 Customer.user 和 CustomerId.userId 属性 共享相同的基础列(在本例中为 user_fk)。

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

它还说:

虽然 JPA 不支持,但 Hibernate 允许您放置关联 直接在嵌入的 id 组件中(而不必使用 @MapsId 注解)。

@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 注释。以下是我的观察:

如果我对CustomerUser 的实体声明是这样的:

@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?,但我无法获得有关此注释的明确信息。

【问题讨论】:

  • 我只使用带有Map 的映射。所以我的映射ID是它的关键。有时,它比ListSet 更方便

标签: java hibernate jpa


【解决方案1】:

@MapsId 用于告诉 hibernate(或任何 JPA 提供者,实际上)使用与该实体一对一关系的另一个实体的相同 id。

这将避免使用额外的列来存储两个实体之间的引用,同时能够具有双向关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 2020-12-14
    相关资源
    最近更新 更多