如果关系表中为空,休眠是否返回 null 或空集合?

2022-09-04 22:32:51

我对一些事情感到好奇。假设我们在员工电话之间有一个简单的关系:

@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @OneToMany(mappedBy="owner")
  private List<Phone> phones;
  ...
}
@Entity
public class Phone {
  @Id
  private long id;
  ...
  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="OWNER_ID")
  private Employee owner;
  ...
}

假设员工没有电话,电话表中没有条目。如果我有一段代码,可以获取员工的电话并出于任何原因对其进行迭代

for (Phone phone : employee.getPhones())
{
     ...
}

getter 是否会重新调谐 NULL 或空集合,并且 getching 策略会发挥作用吗?

如果我没记错的话,休眠有它自己的使用代理收集的实现,对于LAZY fetch,它使用其中之一进行实例化,并在需要时从表中检索数据(如果我错了,则正确)。因此,在调用 getter 时,请尝试从表中检索数据,获取一个空集作为结果并返回一个空集合。(这是我的想法)。或者我应该始终检查 getter 的结果是否为 NULL


答案 1

由于这些集合在默认情况下是懒惰的,因此应返回该集合的代理(例如 或类似),当您访问列表时加载列表元素。employee.getPhones()PersistentList

此外,由于是关系的所有者,Hibernate将不知道是否有员工的电话,因此它必须假设列表存在 - 尽管它可能是空的。也就是说,Hibernate返回null没有多大意义,因为:Phone

  • 休眠需要先尝试加载手机,看看没有
  • 实现集合的延迟加载,不得返回 null,而应返回代理getPhones()
  • 无论如何,返回null将是不好的做法(列表仍然存在,它只是空的)
  • 如果列表为空,则无法添加手机并让Hibernate使用级联等来自动保留该更改(感谢Gimby指出这一点)

使用预先加载不应该改变这一点。Hibernate会知道没有员工的电话,但返回null而不是空列表,这也表示没有电话,仍然没有什么意义(想想允许为加载的员工添加电话,如果使用null进行紧急获取,则代码的差异,您不需要它们, 等)。


答案 2

推荐