EntityBase是其他实体类的基类。在这里我们先将代码贴出。需要说明的是,有些实体类是需要映射到数据库的。需要JPA基础,或者Hibernate基础。
这个类就是包含一个Id,唯一标示、还有就是一个版本号。利于升级。
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@MappedSuperclass
public abstract class EntityBase implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7893439827939854533L;
@Id
@Column(columnDefinition = "BINARY(16)", length = 16, updatable = false, nullable = false)
public UUID getId() {
ensureId();
return id;
}
@Version
private Long version;
public Long getVersion() {
return version;
public void setVersion(Long version) {
this.version = version;
@Override
public boolean equals(Object o) {
// generated by IDEA
if (this == o)
return true;
if (!(o instanceof EntityBase))
return false;
EntityBase that = (EntityBase) o;
return id.equals(that.id);
public int hashCode() {
return id.hashCode();
// JPA
protected EntityBase() {
protected void setId(UUID id) {
this.id = id;
private void ensureId() {
if (id == null)
id = UUID.randomUUID();
private UUID id;
}
在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class)、Joined策略(table per subclass)和Table_PER_Class策略。
1.单表继承策略
单表继承策略,父类实体和子类实体共用一张数据库表,在表中通过一列辨别字段来区别不同类别的实体。具体做法如下:
a.在父类实体的@Entity注解下添加如下的注解:
@Inheritance(Strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”辨别字段列名”)
@DiscriminatorValue(父类实体辨别字段列值)
b.在子类实体的@Entity注解下添加如下的注解:
@DiscriminatorValue(子类实体辨别字段列值)
定义了一个父类
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "WINDOW_FILE")
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
@DiscriminatorValue("WindowFile")
public class WindowFile {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Basic
@Column(name = "NAME")
private String name;
@Column(name = "TYPE")
private String type;
@Column(name = "DATE")
private Date date;
//省略get set
}
后定义2个子类
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@DiscriminatorValue("Folder")
public class Folder extends WindowFile {
@Column(name = "FILE_COUNT")
private Integer fileCount;
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@DiscriminatorValue("Document")
public class Document extends WindowFile {
@Column(name = "SIZE")
private String size;
以上通过列DISCRIMINATOR的不同,区分具体父子实体。
实际表结构如下:
WINDOW_FILE DISCRIMINATOR,ID,NAME,DATE,TYPE,SIZE,FILE_COUNT
当你使用WindowFile实体时,实际表的字段为DISCRIMINATOR='WindowFile',SIZE与FILE_COUNT永远是空
当使用Folder实体时,DISCRIMINATOR='Folder',SIZE永远是空,FILE_COUNT为实际值。
Document同理,与Folder类似。
2.Joined策略
父类实体和子类实体分别对应数据库中不同的表,子类实体的表中只存在其扩展的特殊属性,父类的公共属性保存在父类实体映射表中。具体做法:
@Inheritance(Strategy=InheritanceType.JOINED)
子类实体不需要特殊说明。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@Table(name = "T_ANIMAL")
@Inheritance(strategy = InheritanceType.JOINED)
public class Animal {
@Column(name = "ID")
@Column(name = "COLOR")
private String color;
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@Table(name = "T_BIRD")
@PrimaryKeyJoinColumn(name = "BIRD_ID")
public class Bird extends Animal {
@Column(name = "SPEED")
private String speed;
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@Table(name = "T_DOG")
@PrimaryKeyJoinColumn(name = "DOG_ID")
public class Dog extends Animal {
@Column(name = "LEGS")
private Integer legs;
T_ANIMAL ID,COLOR,NAME
T_BIRD SPEED,BIRD(既是外键,也是主键)
T_DOG LEGS,DOG_ID(既是外键,也是主键)
3.Table_PER_Class策略:
Table_PER_Class策略,父类实体和子类实体每个类分别对应一张数据库中的表,子类表中保存所有属性,包括从父类实体中继承的属性。具体做法:
只需在父类实体的@Entity注解下添加如下注解:
@Inheritance(Strategy=InheritanceType.TABLE_PER_CLASS)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "T_VEHICLE")
public class Vehicle { // 基类
// @GeneratedValue
private Integer speed;// 速度
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyFGdz9lbvNWavw1cldWYtl2Lc12bj5SZ5VGdp5yYjpnen5WZoNWdop3Lc9CX6MHc0RHaiojIsJye.png)
@Table(name = "T_CAR")
public class Car extends Vehicle {
@Column(name = "ENGINE")
private String engine;// 发动机
一旦使用这种策略就意味着你不能使用AUTO generator 和IDENTITY generator,即主键值不能采用数据库自动生成。
T_VEHICLE ID,SPEED
T_CAR ID,SPEED,ENGINE
@MappedSuperclass注解是为了在继承中,防止基类生成表格。在基类加上该标注,而不是@Entity,就可以只生成子类表,而子类表又含有基类的那些属性(列)。
实体类baseEntity.java
package com.rock.cft.hibernate;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
public abstract class BaseEntity {
private Integer id;// 数据库主键
private Date creationTime;//创建时间
private Date modificationTime;//修改时间
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
public Date getCreationTime() {
return creationTime;
public void setCreationTime(Date creationTime) {
this.creationTime = creationTime;
public Date getModificationTime() {
return modificationTime;
public void setModificationTime(Date modificationTime) {
this.modificationTime = modificationTime;
package com.rock.cft.test.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import com.rock.cft.hibernate.BaseEntity;
@Entity
@Table(name="test_no2")
public class Test_No1 extends BaseEntity implements Serializable {
private String name;
private int age;
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public int getAge() {
return age;
public void setAge(int age) {
this.age = age;
public class Test_NO2 extends BaseEntity implements Serializable {
private Date testBri;
private String testAdr;
public Date getTestBri() {
return testBri;
public void setTestBri(Date testBri) {
this.testBri = testBri;
public String getTestAdr() {
return testAdr;
public void setTestAdr(String testAdr) {
this.testAdr = testAdr;
关于定义那些列的等具体细节,这里就不再说明了。