Hibernate 的行为 get vs load with discriminator
Behavior of Hibernate get vs load with discriminator
我想知道为什么 hibernate 的“获取”和“加载”行为对于受歧视的实体有不同的表现?
映射:
@Entity
@Table(name = "person")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "type")
public abstract class BasePerson {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
protected Integer id;
@Column(name = "name")
private String name;
...
@Entity
@DiscriminatorValue("COMPANY")
public class Company extends BasePerson {
...
@Entity
@DiscriminatorValue("CITIZEN")
public class Citizen extends BasePerson {
...
以下调用 returns 特定子实体(公司或公民):
(BasePerson) hibernateTemplate.getSessionFactory().getCurrentSession().get(BasePerson.class, id);
下面只调用returns超级实体BasePerson:
(BasePerson) hibernateTemplate.getSessionFactory().getCurrentSession().load(BasePerson.class, id);
为什么会这样?我如何使用 load() 但获得具体实现(Citizen 或 Company 对象)?
这是因为 load()
不会触发 SELECT 语句。它只是为您使用您传递的 ID 传递的 class 创建一个代理。稍后当您在该代理上调用方法时 - Hibernate 将从 DB 获取 SELECT 数据。但那时它无法更改已存在对象的 class,因此在这种情况下,您将始终使用超级 class。
在实践中,如果您在实体中的某处引用具有惰性 OTM 或 OTO 关系的层次结构的超级 class,通常会发生这种情况。由于该字段是惰性的,ORM 还将创建它知道的任何 class 的代理(在这种情况下它是超级 class)。
PS:load()
可以 return 一个实体而不是代理,但前提是该实体已经被其他代码加载并且它已经驻留在会话中。
我想知道为什么 hibernate 的“获取”和“加载”行为对于受歧视的实体有不同的表现?
映射:
@Entity
@Table(name = "person")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "type")
public abstract class BasePerson {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
protected Integer id;
@Column(name = "name")
private String name;
...
@Entity
@DiscriminatorValue("COMPANY")
public class Company extends BasePerson {
...
@Entity
@DiscriminatorValue("CITIZEN")
public class Citizen extends BasePerson {
...
以下调用 returns 特定子实体(公司或公民):
(BasePerson) hibernateTemplate.getSessionFactory().getCurrentSession().get(BasePerson.class, id);
下面只调用returns超级实体BasePerson:
(BasePerson) hibernateTemplate.getSessionFactory().getCurrentSession().load(BasePerson.class, id);
为什么会这样?我如何使用 load() 但获得具体实现(Citizen 或 Company 对象)?
这是因为 load()
不会触发 SELECT 语句。它只是为您使用您传递的 ID 传递的 class 创建一个代理。稍后当您在该代理上调用方法时 - Hibernate 将从 DB 获取 SELECT 数据。但那时它无法更改已存在对象的 class,因此在这种情况下,您将始终使用超级 class。
在实践中,如果您在实体中的某处引用具有惰性 OTM 或 OTO 关系的层次结构的超级 class,通常会发生这种情况。由于该字段是惰性的,ORM 还将创建它知道的任何 class 的代理(在这种情况下它是超级 class)。
PS:load()
可以 return 一个实体而不是代理,但前提是该实体已经被其他代码加载并且它已经驻留在会话中。