如果表使用联合主键(一个表有两个以上的主键),你可以映射类的多个属性为标识符属性。如:<composite-id>元素接受<key-property> 属性映射(单表映射)和<key-many-to-one>属性映射作为子元素(多表映射)。
       <composite-id>
            <key-property name="stationNum" type="java.lang.String" column="STATIONNUM"/>
            <key-property name="observTimes" type="java.util.Date" column="OBSERVTIMES"/>
        </composite-id>
在持久化类必须重载equals()和hashCode()方法,来实现组合的标示符的相等判断,实现Serializable接口也是必须的。
不幸的是,这种组合关键字的方法意味着一个持久化类是它自己的标识。除了对象自己之外, 没有什么方便的“把手”可用。你必须初始化持久化类的实例,填充它的标识符属性,再load() 组合关键字关联的持久状态。我们把这种方法称为embedded(嵌入式)的组合标识符,在重要的应用中不鼓励使用这种用法。
第二种方法我们称为mapped(映射式)组合标识符 (mapped composite identifier),<composite-id>元素中列出的标识属性不但在持久化类出现,还形成一个独立的标识符类。
      <composite-id name="id" class="hibernate.RainId">
            <key-property name="stationNum" type="string">
                <column name="StationNum" length="5" />
            </key-property>
            <key-property name="observTimes" type="timestamp">
                <column name="ObservTimes" length="19" />
            </key-property>
        </composite-id>
在这个例子中,组合标示符类RainId和实体类都含有stationNum和observTimes属性,标示符必须重载equals()和hashCode()并且实现Serializable接口。这种方法的缺点是出现了明显的代码重复。
下面列出的属性是用来指定一个映射式组合标识符的:

mapped (可选, 默认为false): 指明使用一个映射式组合标识符,其包含的属性映射同时在实体类和组合标识符类中出现。
class (可选,但对映射式组合标识符必须指定): 作为组合标识符类使用的类名. 
 
name (可选,但对这种方法而言必须): 包含此组件标识符的组件类型的名字.
access (可选 - 默认为property):
hibernate应该使用的访问此属性值的策略
class (可选 - 默认会用反射来自动判定属性类型 ): 用来作为组合标识符的组件类的类名
第三种方式,被称为identifier component(标识符组件)是我们对几乎所有应用都推荐使用的方式。
例子:
POJO类
             public class Rain implements java.io.Serializable {
                 private RainId id;//联合主键
                 private Date insertTimes;
                 private Integer precipitation;
                 private Integer threePrecip;
                 private Integer sixPrecip;
                 private Integer twelvePrecip;
                 private Integer twentyFourPrecip;
                 private Integer minuteRain0;
                 private Integer minuteRain1;
联合主键bean
public class RainId implements java.io.Serializable {
    private String stationNum;
    private Date observTimes;
    public RainId() {
    }
    public RainId(String stationNum, Date observTimes) {
        this.stationNum = stationNum;
        this.observTimes = observTimes;
    }
 //重写equals 和hashcode方法
    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof RainId))
            return false;
        RainId castOther = (RainId) other;
        return ((this.getStationNum() == castOther.getStationNum()) || (this
                .getStationNum() != null && castOther.getStationNum() != null && this
                .getStationNum().equals(castOther.getStationNum())))
                && ((this.getObservTimes() == castOther.getObservTimes()) || (this
                        .getObservTimes() != null
                        && castOther.getObservTimes() != null && this
                        .getObservTimes().equals(castOther.getObservTimes())));
    }
    public int hashCode() {
        int result = 17;
        result = 37
                * result
                + (getStationNum() == null ? 0 : this.getStationNum()
                        .hashCode());
        result = 37
                * result
                + (getObservTimes() == null ? 0 : this.getObservTimes()
                        .hashCode());
        return result;
    }
配置映射文本 hbm.xml
 <class name="hibernate.Rain" table="rain" catalog="base">
        <composite-id name="id" class="hibernate.RainId">
            <key-property name="stationNum" type="string">
                <column name="StationNum" length="5" />
            </key-property>
            <key-property name="observTimes" type="timestamp">
                <column name="ObservTimes" length="19" />
            </key-property>
        </composite-id>
        <property name="insertTimes" type="timestamp">
            <column name="InsertTimes" length="19" />
        </property>
 
 
缺点:
1、联合主键当中的字段不应该存在空值

   在实际的开发当中我发现,如果联合主键中的某一字段为空值,那么将会导致通过该联合主键查询出来的结果为空值,这个问题不知道是hibernate的bug还是spring集成hibernate时产生的问题,总之在实际使用的时候最好保证作为联合主键的字段都是有值的。
2、主键容易冲突

   hibernate联合主键的另一个弊端就是存在主键重复的隐患,如果将某几个字段做为联合主键,在这些字段更新之后很可能造成重复,但数据库中并不会报错(存在其他不相同的字段),然而hibernate却会报主键重复的错误。

hibernate 联合主键 composite-id的更多相关文章

  1. hibernate 联合主键生成机制(组合主键XML配置方式)

    hibernate 联合主键生成机制(组合主键XML配置方式)   如果数据库中用多个字段而不仅仅是一个字段作为主键,也就是联合主键,这个时候就可以使用hibernate提供的联合主键生成策略. 具体 ...

  2. 这是一个hibernate 联合主键的例子

    package com.bird.entity; import java.io.Serializable; import javax.persistence.Entity; import javax. ...

  3. Java进阶知识05 Hibernate联合主键之Annotation(注解)和XML实现方式

    1.Hibernate联合主键(Annotation实现) 1.1.单列主键 1.1.1.为什么要有主键? //唯一确定一条记录    1.1.2.一个表能否有多个主键? //不能    1.1.3. ...

  4. hibernate 联合主键

      xml方式处理联合主键:   以有两个主键:id和name的student表为例. 先创建个主键类:   package com.bjsxt.hibernate; //黑色为必写项 public ...

  5. Hibernate联合主键映射

    1.联合主键的映射规则 1) 类中的每个主键属性都对应到数据表中的每个主键列. Hibernate要求具有联合主键的实体类实现Serializable接口,并且重写hashCode与equals方法, ...

  6. hibernate ——联合主键

    接上一篇博客:http://www.cnblogs.com/tengpan-cn/p/5551323.html 主键类不需要写任何注解,表对象类使用@IdClass注解 在表对象类前面加@IdClas ...

  7. hibernate联合主键 注解方式

    转载自https://my.oschina.net/yotoo/blog/265571 方法一:主键类用@Embeddable,pojo类仍然用@Entity但是引用主键类的对象用@Id 主键pojo ...

  8. hibernate联合主键注解配置

    在网上看到好多方法,结果拿来用还是出现了一些问题.现在整理一下 1.主键类 import javax.persistence.Column; public class UserRoleUionPK i ...

  9. hibernate联合主键注解方式

    方法一:主键类用@Embeddable,pojo类仍然用@Entity但是引用主键类的对象用@Id 主键pojo类: @Embeddable public class composeIdPK impl ...

随机推荐

  1. php 23种设计模型 - 适配器模式

    适配器模式(Adapter) 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能. 这种模式涉及到一个单一的类, ...

  2. cURL error 60: SSL certificate problem: unable to get local issuer certifica 解决

    从 https://curl.haxx.se/docs/caextract.html 上下载cacert.pem 打开php.ini  搜索curl.cainfo 与 openssl.cafile,将 ...

  3. CF1515H口胡

    居然一下就做出来了...不知道是不是对的/fad 考虑操作的本质,首先将所有元素插入线段树中. 来依次考虑每一种操作: 区间与 注意到这个操作类似将某些节点的右儿子合并到左儿子上,而一个节点最多被合并 ...

  4. VuePress 博客之 SEO 优化(二)重定向

    前言 在 <一篇带你用 VuePress + Github Pages 搭建博客>中,我们使用 VuePress 搭建了一个博客,最终的效果查看:TypeScript 中文文档. 本篇讲讲 ...

  5. oracle中regexp_like/instr/substr/replace介绍和例子

    ORACLE中的支持正则表达式的函数主要有下面四个: 1,REGEXP_LIKE :与LIKE的功能相似 2,REGEXP_INSTR :与INSTR的功能相似 3,REGEXP_SUBSTR :与S ...

  6. python+pytest接口自动化(10)-session会话保持

    在接口测试的过程中,经常会遇到有些接口需要在登录的状态下才能请求,否则会提示请登录,那么怎样解决呢? 上一篇文章我们介绍了Cookie绕过登录,其实这就是保持登录状态的方法之一. 另外一种方式则是通过 ...

  7. 【freertos】002-posix模拟器设计与cortex m3异常处理

    目录 前言 posix 标准接口层设计 模拟器的系统心跳 模拟器的task底层实质 模拟器的任务切换原理 cortex M3/M4异常处理 双堆栈指针 双操作模式 栈帧 EXC_RETURN 前言 如 ...

  8. Redis Cluster 集群搭建与扩容、缩容

    说明:仍然是伪集群,所有的Redis节点,都在一个服务器上,采用不同配置文件,不同端口的形式实现 前提:已经安装好了Redis,本文的redis的版本是redis-6.2.3 Redis的下载.安装参 ...

  9. VUE开发--环境配置(一)(转)

    无剑_君关注 0.312019.05.09 11:53:43字数 1,073阅读 19,627        https://www.jianshu.com/p/a494417def99?utm_so ...

  10. Docker容器内连接宿主机即CentOS的Mysql服务器

    docker的宿主机是虚拟机下的CentOS 博主最近遇到一种情况,从服务器拷贝了一份数据库在宿主机Mysql服务器上,想要用本地的数据库测试自己的代码正确性,但是项目程序都是靠docker一键部署的 ...