初始化或不初始化 JPA 关系映射?

2022-09-01 21:03:43

在一对多 JPA 关联中,是否认为将关系初始化为空集合是一种最佳实践?例如。

@Entity
public class Order { 

   @Id
   private Integer id;

   // should the line items be initialized with an empty array list or not?
   @OneToMany(mappedBy="order")
   List<LineItem> lineItems = new ArrayList<>();

}

在上面的示例中,是否最好使用默认值为空来定义?有哪些优点和缺点?lineItemsArrayList


答案 1

JPA 本身并不关心集合是否已初始化。当使用 JPA 从数据库中检索订单时,JPA 将始终返回具有非空订单行列表的订单。

原因:因为订单可以有 0、1 或 N 行,最好使用空的、一个大小或 N 大小的集合进行建模。如果集合为 null,则必须在代码中的任何位置检查该值。例如,如果列表为 null,则此简单循环将导致 NullPointerException:

for (OrderLine line : order.getLines()) {
    ...
}

因此,最好通过始终具有非 null 集合来使其成为不变量,即使对于新创建的实体实例也是如此。这使得创建新订单的生产代码更安全、更清洁。这也使得使用不是来自数据库的 Order 实例的单元测试更安全、更干净。


答案 2

我还建议使用番石榴的不可变集合,例如:

import com.google.common.collect.ImmutableList;
// ...
@OneToMany(mappedBy="order")
List<LineItem> lineItems = ImmutableList.of();

此成语从不创建新的空列表,而是重用表示空列表的单个实例(类型无关紧要)。这是函数式编程语言的一种非常常见的做法(Scala也这样做),并且将具有空对象而不是空值的开销减少到,这使得任何反对成语的效率论证都没有意义。


推荐