JPA规范定义了一种特殊的实体类,这种实体类在实体的多在继承时使用,该类可以不映射为指定的一个表,但该类仍可定义可持久化的属性,这些可以被它的子类继承。这类实体使用标记@MappedSuperclass注释标记。
例如,将ContractEmployeeEO实体定义为非映射实体的代码,如下所示:
@DiscriminatorValue("contract")
@MappedSuperclass
public class ContractEmployeeEO extends EmployeeEO {
private Date createDate;
private Date expiredDate;
@Column(name="create_date")
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
@Column(name="expired_date")
public Date getExpiredDate() {
return expiredDate;
}
public void setExpiredDate(Date expiredDate) {
this.expiredDate = expiredDate;
}
}
在使用被标注@MappedSuperclass的实体时需要注意以下几个问题:
l 此实体不对应数据库中的指定表,所以不能创建该类的实体,例如以下代码:
ContractEmployeeEO contractor = new ContractEmployeeEO();
contractor.setName("Micheal");
contractor.setCreateDate(new Date(System.currentTimeMillis()));
contractor.setExpiredDate(new Date(System.currentTimeMillis()));
entityManager.persist(contractor);
虽然能够编译通过,但运行时由于该实体是一个不能创建的实体,所以运行时会抛出异常。
l 同样,也不能使用该实体进行EQL查询,例如以下查询SQL是不正确的。
SELECT
employee
FROM
ContractEmployeeEO employee
l 在该实体类中,可以增加可持久化的属性,这些属性虽然不能在该实体中使用,但自动被继承它的子类使用。例如继承该实体的子类FTEmployeeEO实体代码如下所示:
@Entity
@DiscriminatorValue("fulltime")
public class FTEmployeeEO extends ContractEmployeeEO {
// ContractEmployeeEO类中的createDate自动继承,并映射到create_date字段中
// ContractEmployeeEO类中的expiredDate自动继承,并映射到expired _date字段中
}
l 其子类中,若要覆盖@MappedSuperclass中的定义的属性,可以配合使用@AttributeOverride标记,指明覆盖的属性。
例如,这里在表中增加两个字段“ft_create_date”,“ft_expired_date”的SQL脚本如下:
CREATE TABLE tb_employee (
id int(20) NOT NULL auto_increment,
name varchar(255) ,
vacation_days int(10),
create_date date,
expired_date date,
monthly_salary double(10,2),
hourly_salary double(10,2),
worked_hours int(10),
employee_type varchar(32),
ft_create_date date,
ft_expired_date date,
PRIMARY KEY (id)
);
此时,重新映射FTEmployeeEO类中的属性createDate,将createDate属性映射到“ft_create_date”字段中,而不使用ContractEmployeeEO属性createDate,映射到“create_date”字段中,代码如下所示:
@Entity
@DiscriminatorValue("fulltime")
@AttributeOverride(name="createDate", column=@Column(name="ft_create_date"))
public class FTEmployeeEO extends ContractEmployeeEO {
//代码省略
}
若此时将“createDate”和“expiredDate”分别覆盖父类中的属性映射定义,则需要使用@AttributeOverrides属性,代码如下所示。
@Entity
@DiscriminatorValue("fulltime")
@AttributeOverrides( {
@AttributeOverride(name = "expiredDate", column = @Column(name = "ft_expired_date")),
@AttributeOverride(name = "createDate", column = @Column(name = "ft_create_date"))
}
)
public class FTEmployeeEO extends ContractEmployeeEO {
//代码省略
}