当前位置: 首页 > 知识库问答 >
问题:

理解Hibernate中的@MapsId注释

薛文斌
2023-03-14

根据Hibernate留档,@MapsId注释的解释如下:

在嵌入式id对象中,关联表示为关联实体的标识符。但您可以通过@MapsId注释将其值链接到实体中的常规关联。@MapsId值对应于包含关联实体标识符的嵌入式id对象的属性名称。在数据库中,这意味着客户。用户和客户ID。userId属性共享相同的基础列(本例中为user\u 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,但它允许您将关联直接放置在嵌入式idhtml" target="_blank">组件中(而不必使用@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注释。以下是我的观察结果:

如果我对客户和用户的实体声明如下:

@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

现在,如果我将我的客户实体更改为:

@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

在本例中,我看到了两个额外的列(firstname

我是Hibernate的新手,所以我发现很难理解Hibernate文档中给出的解释,@MapsId的目的是什么,何时我们必须使用它以及它如何影响底层数据库模式。

我也看了这篇SO帖子——有人能解释一下Hibernate中的@MapsId吗?但是我无法获得关于这个注释的明确信息。

共有1个答案

梁丘伟
2023-03-14

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

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

 类似资料:
  • 我试图理解JPA中注释的属性。我创建了以下示例,其中客户有一个订单列表: 现在,当我使用Hibernate生成表时,我看到Hibernate只创建了2个表: 另外,如果我试图保存一个客户和一些订单,我会看到下面由Hibernate生成的DML语句: 为什么hibernate尝试在TBL_ORDER中插入和更新记录,而不是仅仅运行一个插入查询? 现在,如果我删除mappedBy属性并尝试生成表,那么

  • 我试图在JPA2.1中保存一个实体。我有三个表--MVCollection、MVCollectionVersion(它是MVCollection的版本)和MVBelomsCollection(它是属于一个版本的项)。MVCollection的主键是生成的序列号。当我生成一个带有版本(不包含任何项)的集合时,我使用@mapsid,生成的ID在子级中使用。然而,我似乎不能理解我如何能复制这与项目。 M

  • 问题内容: 我试图了解JPA 中注释的属性。我在下面的示例中创建了一个客户具有订单列表的示例: 现在,当我使用Hibernate生成表时,我看到Hibernate仅创建了2个表: 另外,如果我尝试保存客户和一些订单,我会在下面看到由Hibernate生成的DML语句: 为什么Hibernate试图在TBL_ORDER中插入和更新记录,而不仅仅是运行单个插入查询? 现在,如果我删除mapledBy属

  • Hibernate留档在@BatchSize上提供了一些信息,如下所示: @BatchSize指定一个“批量大小”,用于按标识符获取此类实例。尚未加载的实例一次加载一个批大小(默认值为1)。 我不清楚这个注释的目的是什么,什么时候我们需要使用它。请帮助我理解何时使用这个注释。

  • 问题内容: 有一个结构。我想以这种方式链接这三个实体:公司应包含ID,公司名称和部门列表,每个部门都有一个工人列表,ID和部门名称。每个工人都有名字,身份证。 我试图与一对多和多对一建立联系,但未成功。 公司 部 工人 我从开始: 它填充公司,但不填充其他表,也没有创建任何联接(映射)错误: 问题答案: 除了Glenn Lane的答案中提到的级联,您还需要了解双向关联是如何工作的。 它们有一个所有

  • 问题内容: 从官方的hibernate文档中: @ org.hibernate.annotations.Type会覆盖所使用的默认hibernate类型:由于Hibernate可以正确推断出该类型,因此通常不必这样做 文档中有一个示例: 我不明白 我们声明,但是方法的返回值具有类型。 我希望在类型注释中声明的类型和返回值的类型应该是相同的类型。 有人无法解释在注解中声明的类型的实际用途。为什么它与