如果关系中的表为空,Hibernate是返回null还是空集合?

And*_*eou 11 java hibernate

我很好奇某事.假设我们在员工电话之间有一个简单的关系:

@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;
  ...
}
Run Code Online (Sandbox Code Playgroud)

我们假设一个员工没有电话,电话表中没有条目.如果我有一段代码可以获取Employee的电话并因任何原因迭代它们

for (Phone phone : employee.getPhones())
{
     ...
}
Run Code Online (Sandbox Code Playgroud)

getter会重新调整NULL还是空集合,并且getching策略会起作用.

如果我没记错的话,hibernate有自己的代理实现,使用代理和LAZY提取,它实例化其中一个,并在需要时从表中检索数据(如果我错了,请更正).因此,在调用getter时尝试从表中检索数据,得到一个空集作为结果并返回一个空集合.(这是我的想法).或者我应该总是检查getter的结果是否为NULL

Tho*_*mas 5

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

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

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

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