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

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

问题描述

在这段代码中,如何为复合键生成一个Java类(如何在hibernate中复合键):

 创建表时间(
levelStation int(15)非空,
src varchar(100)非空,
dst varchar(100)非空,
距离int(15)不是(15)非空,
confPathID int(15)非空,
约束ConfPath_fk外键(confPathID)引用ConfPath(confPathID),
主键levelStation,confPathID)
)ENGINE = InnoDB DEFAULT CHARSET = utf8;


解决方案

要映射组合键,可以使用 EmbeddedId IdClass 注释。我知道这个问题不是严格的JPA,但规范定义的规则也适用。因此,它们是:

lockquote

2.1.4主键和实体标识

...

复合主键必须
对应于单个
持久字段或属性或
这样的集合字段或属性为
,如下所述。主键类
必须定义为表示
复合主键。当
数据库键由多个
列组成时,复合
主键通常在从旧数据库映射
时出现。 EmbeddedId
IdClass 注释用于
表示复合主键。

第9.1.14和9.1.15节。



...



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




  • 主键类必须是公共的,并且必须有一个公共无参数
    构造函数

  • 如果使用基于属性的访问,主键
    的属性必须是public或protected。

  • 主键类必须是 serializable

  • 主键类
    必须定义等于 hashCode
    方法。
    这些方法的值
    相等的语义必须是

    键映射到的数据库类型的数据库相等
    一致。

  • 复合主键必须e ither被表示和映射为一个
    嵌入类(参见9.1.14节,
    EmbeddedId Annotation),或者必须是
    表示并映射到多个
    字段或属性实体
    类(见第9.1.15节IdClass
    注释)。
  • 如果复合主键类映射到多个字段或
    实体类的属性,主键类的
    名称或主键类
    中的
    属性,以及实体类中的
    属性必须是
    对应,并且它们的类型必须是$



  • 使用 IdClass

    组合主键的类可能看起来像(可能是一个静态内部类):

      public class TimePK实现Serializable {
    protected Integer levelStation;
    保护整数confPathID;

    public TimePK(){}

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

    实体:

    $ $ p $ @Entity
    @IdClass(TimePK.class)
    类实现Serializable的时间{
    @Id
    私人整数levelStation;
    @Id
    私人整数confPathID;

    private String src;
    private String dst;
    私人整数距离;
    私人整数价格;

    // getters,setters
    }

    IdClass 注释将多个字段映射到表PK。

    With EmbeddedId



    主键可能看起来像(可能是一个静态内部类):

      @Embeddable 
    public class TimePK implements Serializable {
    保护整数levelStation;
    保护整数confPathID;

    public TimePK(){}

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

    实体:
    $ b $ pre $ @Entity
    类实现可序列化的时间{
    @EmbeddedId
    private TimePK timePK ;

    private String src;
    private String dst;
    私人整数距离;
    私人整数价格;

    // ...
    }

    @EmbeddedId 注解将一个PK类映射到表PK。



    差异:




    • 从物理模型的角度来看,没有区别
    • @EmbeddedId 莫名其妙更清楚地表明,关键是一个复合关键字,当组合关键字pk是一个有意义的实体本身或它在代码中重用时,它是有意义的
    • code> @IdClass 用于指定某些字段组合是唯一的,但这些字段没有特殊含义。



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


    • IdClass

        select t.levelStation from时间t 


    • with EmbeddedId

       选择时间t.timePK.levelStation t 




    参考文献




    • JPA 1.0规范


      • 第2.1.4节主键和实体标识
      • 第9.1.14节 EmbeddedId Annotation
      • 第9.1.15节IdClass批注



    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;
    

    解决方案

    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 Primary Keys and Entity Identity

    ...

    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:

    • 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.

    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
    }
    

    And the entity:

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

    The IdClass annotation maps multiple fields to the table PK.

    With EmbeddedId

    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
    }
    

    And the entity:

    @Entity
    class Time implements Serializable {
        @EmbeddedId
        private TimePK timePK;
    
        private String src;
        private String dst;
        private Integer distance;
        private Integer price;
    
        //...
    }
    

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

    Differences:

    • 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):

    • with IdClass

      select t.levelStation from Time t
      

    • with EmbeddedId

      select t.timePK.levelStation from Time t
      

    References

    • 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"

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

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