如何使用JPA和Hibernate映射组合键? [英] How to map a composite key with JPA and Hibernate?

查看:104
本文介绍了如何使用JPA和Hibernate映射组合键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此代码中,如何为组合键生成Java类(如何在休眠状态下组合键):

In this code, how to generate a Java class for the composite key (how to composite key in hibernate):

create table Time (
     levelStation int(15) not null,
     src varchar(100) not null,
     dst varchar(100) not null,
     distance int(15) not null,
     price int(15) not null,
     confPathID int(15) not null,
     constraint ConfPath_fk foreign key(confPathID) references ConfPath(confPathID),
     primary key (levelStation, confPathID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

推荐答案

要映射组合键,可以使用EmbeddedId 批注.我知道这个问题不仅仅涉及JPA,但规范定义的规则也适用.所以他们在这里:

To map a composite key, you can use the EmbeddedId or the IdClass annotations. I know this question is not strictly about JPA but the rules defined by the specification also applies. So here they are:

2.1.4主键和实体身份

...

2.1.4 Primary Keys and Entity Identity

...

复合主键必须 对应于一个 永久性的领域或财产或 此类字段或属性的集合,例如 如下面所描述的.主键类 必须定义为代表一个 复合主键.合成的 主键通常在以下情况下出现 从旧数据库映射时 数据库密钥由几个组成 列. EmbeddedIdIdClass批注用于 表示复合主键.请参见 9.1.14和9.1.15节.

A composite primary key must correspond to either a single persistent field or property or to a set of such fields or properties as described below. A primary key class must be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. The EmbeddedId and IdClass annotations are used to denote composite primary keys. See sections 9.1.14 and 9.1.15.

...

以下规则适用于 复合主键:

The following rules apply for composite primary keys:

  • 主键类必须是公共的,并且必须具有公共的无参数 构造函数.
  • 如果使用基于属性的访问,则主键的属性 该课程必须是公开的或受保护的.
  • 主键类必须为serializable.
  • 主键类 必须定义equalshashCode 方法.价值的语义 这些方法的相等性必须是 与数据库相等一致 对于数据库类型 键已映射.
  • 复合主键必须被表示并映射为 可嵌入的类(请参见第9.1.14节, "EmbeddedId Annotation")或必须为 表示并映射到多个 实体的字段或属性 类(请参见第9.1.15节"IdClass 注释").
  • 如果复合主键类映射到多个字段,或者 实体类的属性, 主键字段的名称或 主键类中的属性 而实体类别的实体必须 对应,并且它们的类型必须是 一样.
  • The primary key class must be public and must have a public no-arg constructor.
  • If property-based access is used, the properties of the primary key class must be public or protected.
  • The primary key class must be serializable.
  • The primary key class must define equals and hashCode methods. The semantics of value equality for these methods must be consistent with the database equality for the database types to which the key is mapped.
  • A composite primary key must either be represented and mapped as an embeddable class (see Section 9.1.14, "EmbeddedId Annotation") or must be represented and mapped to multiple fields or properties of the entity class (see Section 9.1.15, "IdClass Annotation").
  • If the composite primary key class is mapped to multiple fields or properties of the entity class, the names of primary key fields or properties in the primary key class and those of the entity class must correspond and their types must be the same.

使用IdClass

复合主键的类可能看起来像(可以是静态内部类):

With an IdClass

The class for the composite primary key could look like (could be a static inner class):

public class TimePK implements Serializable {
    protected Integer levelStation;
    protected Integer confPathID;

    public TimePK() {}

    public TimePK(Integer levelStation, Integer confPathID) {
        this.levelStation = levelStation;
        this.confPathID = confPathID;
    }
    // equals, hashCode
}

实体:

@Entity
@IdClass(TimePK.class)
class Time implements Serializable {
    @Id
    private Integer levelStation;
    @Id
    private Integer confPathID;

    private String src;
    private String dst;
    private Integer distance;
    private Integer price;

    // getters, setters
}

IdClass批注将多个字段映射到表PK.

The IdClass annotation maps multiple fields to the table PK.

复合主键的类可能看起来像(可以是静态内部类):

The class for the composite primary key could look like (could be a static inner class):

@Embeddable
public class TimePK implements Serializable {
    protected Integer levelStation;
    protected Integer confPathID;

    public TimePK() {}

    public TimePK(Integer levelStation, Integer confPathID) {
        this.levelStation = levelStation;
        this.confPathID = confPathID;
    }
    // equals, hashCode
}

实体:

@Entity
class Time implements Serializable {
    @EmbeddedId
    private TimePK timePK;

    private String src;
    private String dst;
    private Integer distance;
    private Integer price;

    //...
}

@EmbeddedId批注将PK类映射到表PK.

The @EmbeddedId annotation maps a PK class to table PK.

  • 从物理模型的角度来看,没有区别
  • @EmbeddedId以某种方式更清楚地传达了密钥是组合密钥,而当组合的pk本身是有意义的实体或在您的代码中重用时,IMO就有意义.
  • @IdClass 可用于指定某些字段组合是唯一的,但这些字段没有特殊含义.
  • From the physical model point of view, there are no differences
  • @EmbeddedId somehow communicates more clearly that the key is a composite key and IMO makes sense when the combined pk is either a meaningful entity itself or it reused in your code.
  • @IdClass is useful to specify that some combination of fields is unique but these do not have a special meaning.

它们还影响您编写查询的方式(使它们或多或少变得冗长):

They also affect the way you write queries (making them more or less verbose):

  • IdClass

select t.levelStation from Time t

  • EmbeddedId

    select t.timePK.levelStation from Time t
    

    • JPA 1.0规范
      • 第2.1.4节主键和实体标识"
      • 第9.1.14节"EmbeddedId注释"
      • 第9.1.15节"IdClass注释"
      • JPA 1.0 specification
        • Section 2.1.4 "Primary Keys and Entity Identity"
        • Section 9.1.14 "EmbeddedId Annotation"
        • Section 9.1.15 "IdClass Annotation"

        这篇关于如何使用JPA和Hibernate映射组合键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆