【问题标题】:Behavior of Hibernate get vs load with discriminatorHibernate 的行为 get vs load with discriminator
【发布时间】:2021-12-17 14:34:29
【问题描述】:

我想知道为什么休眠的“get”和“load”在区分实体方面表现不同?

映射:

@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 {

    ...

以下调用返回特定的子实体(公司或公民):

(BasePerson) hibernateTemplate.getSessionFactory().getCurrentSession().get(BasePerson.class, id);

以下调用仅返回超级实体 BasePerson:

(BasePerson) hibernateTemplate.getSessionFactory().getCurrentSession().load(BasePerson.class, id);

为什么会这样?如何使用 load() 但获取具体实现(Citizen 或 Company 对象)?

【问题讨论】:

标签: java hibernate


【解决方案1】:

这是因为load() 不会触发 SELECT 语句。它只是为您使用您传递的 ID 传递的类创建一个代理。稍后当您在该代理上调用方法时 - Hibernate 将从数据库中选择数据。但此时它无法更改已经存在的对象的类,因此在这种情况下您将始终使用超类。

实际上,如果您在实体中的某处引用具有惰性 OTM 或 OTO 关系的层次结构的超类,通常会发生这种情况。由于该字段是惰性的,ORM 还将创建它所知道的任何类的代理(在这种情况下,它是超类)。

PS:load() 可以返回实体而不是代理,但前提是该实体已由其他代码加载并且它已驻留在 Session 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 2023-03-12
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    相关资源
    最近更新 更多