JPA 实体继承:为惰性初始化创建哪个实例?
JPA entity inheritance: which instance to create for lazy initialization?
JPA 实体继承:为惰性初始化创建哪个实例?例如,
单一table映射策略:
Teacher(abstract)
/ \
FullTimeTeacher PartTimeTeacher
实体学校参考老师:
@Entity
public class School {
@ManyToOne(fetch=FetchType.LAZY)
private Teacher manager;
}
从数据库中检索学校实体时,学校的管理器是懒惰的,没有初始化。将实例化哪种类型的代理?老师很抽象。
代理可能与实际参考类型(全职或兼职教师)不匹配。
我自己很好奇,并使用以下设置对其进行了测试:
@Entity
public class Garage {
@Id
@GeneratedValue
private Long id;
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
private Car car;
...
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
...
}
@Entity
public class SportsCar extends Car {
private int hp;
...
@Override
public String toString() {
return "SportsCar [hp=" + hp + ", getId()=" + getId() + "]";
}
}
测试:
Garage garage = new Garage();
SportsCar car = new SportsCar();
car.setHp(350);
garage.setCar(car);
em.persist(garage);
...
Garage garage = em.find(Garage.class, garage.getId());
System.out.println(garage.getCar().getClass());
System.out.println(garage.getCar());
System.out.println(garage.getCar() instanceof SportsCar);
以上打印:
class com.example.Car_$$_jvstd71_f
SportsCar [hp=350, getId()=1]
false
结论:Hibernate 将创建超类的代理。但是,该代理会将方法调用委托给子类实例。
JPA 实体继承:为惰性初始化创建哪个实例?例如,
单一table映射策略:
Teacher(abstract)
/ \
FullTimeTeacher PartTimeTeacher
实体学校参考老师:
@Entity
public class School {
@ManyToOne(fetch=FetchType.LAZY)
private Teacher manager;
}
从数据库中检索学校实体时,学校的管理器是懒惰的,没有初始化。将实例化哪种类型的代理?老师很抽象。
代理可能与实际参考类型(全职或兼职教师)不匹配。
我自己很好奇,并使用以下设置对其进行了测试:
@Entity
public class Garage {
@Id
@GeneratedValue
private Long id;
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
private Car car;
...
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
...
}
@Entity
public class SportsCar extends Car {
private int hp;
...
@Override
public String toString() {
return "SportsCar [hp=" + hp + ", getId()=" + getId() + "]";
}
}
测试:
Garage garage = new Garage();
SportsCar car = new SportsCar();
car.setHp(350);
garage.setCar(car);
em.persist(garage);
...
Garage garage = em.find(Garage.class, garage.getId());
System.out.println(garage.getCar().getClass());
System.out.println(garage.getCar());
System.out.println(garage.getCar() instanceof SportsCar);
以上打印:
class com.example.Car_$$_jvstd71_f
SportsCar [hp=350, getId()=1]
false
结论:Hibernate 将创建超类的代理。但是,该代理会将方法调用委托给子类实例。