JPA 继承2

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 {

         //代码省略

}

你可能感兴趣的:(JPA)