初始化JPA实体getter中的字段是一种好习惯吗?

在POJO Java bean中,这样的代码可能是有益的,尤其是对于集合:

class POJO { private Collection col; public Collection getCol() { if (col == null) col = new SomeCollection(); return col; } } 

它使得使用POJO的代码可以调用pojo.getCol().isEmpty()而无需额外的空检查,从而使代码更清晰。

假设POJO类是JPA实体,它仍然可以安全吗? 通过将集合从null初始化为空的集合,持久性数据将不会被更改,但是,我们仍在修改对象,因此持久性提供程序可能会在刷新持久性上下文时产生一些副作用。 我们有什么风险? 便携性可能吗?

我强烈反对ORM实体中属性的延迟初始化。

在使用Hibernate进行实体属性的延迟初始化时,我们遇到了一个严重的问题,所以我强烈反对它。 我们看到的问题表现在我们发出搜索请求时发生的保存。 这是因为当加载对象时属性为null,但是当调用getter时它将返回延迟初始化对象,因此hibernate(正确地)认为该对象是脏的并且在发出搜索之前将其保存。

我不认为它是一种好的做法,更像是一些很少需要的优化。 如果SomeCollection的创建非常繁重,也许懒惰的初始化是有意义的。 相反,你可以在声明时初始化它(代码更清洁至少对我来说):

 class POJO { private Collection col = new SomeCollection(); public Collection getCol() { return col; } } 

在刷新或可移植性问题中没有副作用,并且您有一个空检查更少。

通常,最好使用空集合或null(对于集合的字段)。

但我不推荐你在吸气器中的方式。

在我个人看来,上面的“规则”也应该用于对象的内部表示。 所以你做得更好:

 class POJO { private Collection col = new SomeCollection(); 

无论如何,如果你想要更多的保存,你需要保护你更新col参考的每一种方式。 但在JPA应用程序中,这应该是一个非常原始的用例。

延迟初始化非常常见且很好。

在构造函数或变量定义中进行权衡与初始化:

  • 延迟初始化通常更有效,它延迟了创建值的成本,这可能永远不需要或用其他值替换。 这在JPA中非常常见,其中从数据库中读取现有对象,并且始终替换它们的值。
  • 它允许空值具有意义,这在布尔值中更为典型,其中null表示基于在创建时不知道的其他内容而延迟分配的默认值。
  • 如果值是暂时的或者是某些方法,那么延迟初始化可以防止空指针。

精读

  • 如果直接访问该字段,您仍然可以获得空指针。
  • 在变量定义中设置默认值更加清晰。
  • 如果同时使用该对象,则延迟初始化可能是并发问题。