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

时间:2011-10-17 08:44:33

标签: java jpa

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

class POJO {
    private Collection<X> col;

    public Collection<X> getCol() {
        if (col == null)
           col = new SomeCollection<X>();

        return col;
    }
}

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

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

4 个答案:

答案 0 :(得分:20)

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

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

    public Collection<X> getCol() {
        return col;
    }
}

在刷新或可移植性问题上没有任何副作用,并且您只有一个空检查。

答案 1 :(得分:12)

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

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

答案 2 :(得分:2)

一般来说,最好使用空集合或null(对于集合的字段)。

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

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

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

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

答案 3 :(得分:1)

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

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

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

N

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