key 发表于 25-7-2009 20:01:58

JPA与继承的有趣问题

JPA支持POJO,而POJO可以继承,这个东西很有趣。

1. 一个简单的实体package persistence2;

import javax.ejb.*;
import javax.persistence.*;

@Entity
public class MySimpleEntity {
    private Long id;
    private String field01;
    private Double field02;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
      return id;
    }

    public void setId(Long id){
      this.id = id;
    }

    public String getField01(){
      return field01;
    }

    public void setField01(String f){
      this.field01 = f;
    }

    public Double getField02(){
      return field02;
    }

    public void setField02(Double f){
      this.field02 = f;
    }

}下面是这个实体的存贮结果:create table MySimpleEntity (id bigint generated by default as identity (start with 1), field01 varchar(255), field02 double, primary key (id))
INSERT INTO MYSIMPLEENTITY VALUES(1,'Hello world',2.13E0)

key 发表于 25-7-2009 20:06:20

继承后的变化

用一个简单的子类继承它:package persistence2;

import javax.persistence.*;

@Entity
public class MySimpleDerived extends MySimpleEntity {
    private Long derivedId;
    private String field03;

    /*@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getDerivedId() {
      return derivedId;
    }
    */

    public void setDerivedId(Long i){
      this.derivedId = i;
    }

    public String getField03(){
      return field03;
    }

    public void setField03(String f){
      this.field03 = f;
    }
}再看分别存贮MySimpleEntity和MySimpleDerived的对象的结果是:create table MySimpleEntity (DTYPE varchar(31) not null, id bigint generated by default as identity (start with 1), field01 varchar(255), field02 double, field03 varchar(255), primary key (id))
INSERT INTO MYSIMPLEENTITY VALUES('MySimpleEntity',1,'Hello world',2.13E0,NULL)
INSERT INTO MYSIMPLEENTITY VALUES('MySimpleDerived',2,'Hello derived',3.42E0,'I''m derived')总结:
1. 父子两个类采用同一张表
2. 表中第一项为DTYPE,即Data Type,对应存放类名

这样就容易理解为什么在子类中不能再声明@Id子段:因为是同一张表,不能有两个@Id

key 发表于 25-7-2009 20:10:37

如果父类是POJO呢?

这是父类,注意,这里没有声明@Entity,所以父类不是实体类package persistence2;

public class MySimpleNonEntity {
    private String x;
    private String y;

    public String getX(){
      return x;
    }

    public void setX(String x){
      this.x = x;
    }

    public String getY() {
      return y;
    }

    public void setY(String y){
      this.y = y;
    }
}而子类是实体类:package persistence2;

import javax.persistence.*;

@Entity
public class MySimpleDerived2 extends MySimpleNonEntity {
    private Long id;
    private String z;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
      return id;
    }

    public void setId(Long id){
      this.id = id;
    }

    public String getZ(){
      return z;
    }

    public void setZ(String z){
      this.z = z;
    }
}存贮的结果是:create table MySimpleDerived2 (id bigint generated by default as identity (start with 1), z varchar(255), primary key (id))
INSERT INTO MYSIMPLEDERIVED2 VALUES(1,'World')显然,父类中的属性被discard掉了,而表名和子类关联上。

key 发表于 25-7-2009 21:22:46

内嵌式Embeddable/Embedded

采用内嵌式的实体是真的把另一个实体嵌进入的。所以,两个类之间不能有同名的field或propertypackage persistence2;

import javax.persistence.*;

@Embeddable
public class MyEmbeddableEntity {
    private String a;
    private String b;

    public String getA() { return a; }
    public void setA(String a) { this.a = a; }
    public String getB() { return b; }
    public void setB(String b) { this.b = b; }

}package persistence2;

import javax.persistence.*;

@Entity
public class MyEmbeddedEntity {

    private Long id;
    private String ax;
    private MyEmbeddableEntity e;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
      return id;
    }

    public void setId(Long x){
      this.id = x;
    }

    public String getAx() {
      return ax;
    }

    public void setAx(String x){
      ax = x;
    }

    @Embedded
    public MyEmbeddableEntity getE(){
      return e;
    }

    public void setE(MyEmbeddableEntity e){
      this.e = e;
    }
}内嵌后的结果如下:create table MyEmbeddedEntity (id bigint generated by default as identity (start with 1), ax varchar(255), a varchar(255), b varchar(255), primary key (id))
INSERT INTO MYEMBEDDEDENTITY VALUES(1,'MMMMMM','aaa','bbb')
页: [1]
查看完整版本: JPA与继承的有趣问题