在一对多的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<>();
}
在上面的例子中,定义更好 lineItems
默认值为空 ArrayList
或不?优缺点都有什么?
JPA本身并不关心集合是否已初始化。使用JPA从数据库中检索订单时,JPA会 总是 返回带有非空OrderLines列表的Order。
原因:因为订单可以包含0行,1行或N行,并且最好使用空的,一个大小或N个大小的集合建模。如果集合为null,则必须在代码中的任何位置检查它。例如,如果列表为null,则此简单循环将导致NullPointerException:
for (OrderLine line : order.getLines()) {
...
}
因此,最好通过始终具有非空集合使其成为不变量,即使对于新创建的实体实例也是如此。这使得生产代码创建新订单更安全,更清洁。这也使得您的单元测试使用不是来自数据库的Order实例,更安全,更清洁。
JPA本身并不关心集合是否已初始化。使用JPA从数据库中检索订单时,JPA会 总是 返回带有非空OrderLines列表的Order。
原因:因为订单可以包含0行,1行或N行,并且最好使用空的,一个大小或N个大小的集合建模。如果集合为null,则必须在代码中的任何位置检查它。例如,如果列表为null,则此简单循环将导致NullPointerException:
for (OrderLine line : order.getLines()) {
...
}
因此,最好通过始终具有非空集合使其成为不变量,即使对于新创建的实体实例也是如此。这使得生产代码创建新订单更安全,更清洁。这也使得您的单元测试使用不是来自数据库的Order实例,更安全,更清洁。
我还建议使用Guava的不可变集合,例如,
import com.google.common.collect.ImmutableList;
// ...
@OneToMany(mappedBy="order")
List<LineItem> lineItems = ImmutableList.of();
这个成语从不创建一个新的空列表,但重用一个表示空列表的实例(类型无关紧要)。这是函数式编程语言的一种非常常见的做法(Scala也这样做)并减少到 零 拥有空对象而不是空值的开销,使得对成语的任何效率论证都没有实际意义。