是否必须在JPA中实例化集合字段?

时间:2010-10-04 08:02:27

标签: hibernate jpa

我正在阅读一篇文章,其中作者已经实现了这样的实体类:

@Entity
public class Product {

 @OneToMany
 private List<Part> parts; // note the missing "= new ArrayList<Part>();"

 public Product() {
 }

 // getters and setters

}

我总是习惯实例化集合字段,在本例中是parts,可以是内联(private List<Part> parts = new ArrayList<Part>();),也可以是构造函数内部,因为据我记忆,不这样做会导致各种NPE

我认为JPA 2中的事情发生了变化,现在JPA运行时使用运行时字节码增强或反射自动实例化该字段,所以我再试一次,但是如果没有实例化{{{I}我仍然无法工作1}}字段,否则parts将抛出NPE。

所以我的问题是,如果不使用Hibernate作为提供程序在Java SE和Java EE环境中实例化aProduct.getParts().add(aPart)字段,是否可以使这项工作成为可能?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:9)

我的理解是JPA提供程序只能在从DB加载的实体中正确实例化该字段。但是,如果您创建一个新的(暂时的)实体,则必须确保所有字段都有效。请注意,在您实际将其附加到持久性上下文之前,Hibernate / JPA不知道新创建的瞬态实体。如果你考虑它,它是合乎逻辑的(至少对我来说):如果你依靠JPA / Hibernate来正确地实例化你的对象,你会建立一个强大的,侵入性的实现依赖,这将使它变得非常困难没有它就不可能再工作了。

因此,对于从未重新创建的实体,只保留未加初始化的集合属性可能没问题。对于您也创建新实例的类,解决此问题的最简单方法是提供两个构造函数:Hibernate / JPA的默认值,以及“手动”创建的参数化构造函数。如果您没有要设置的参数,您还可以创建一个静态工厂方法,以使用默认值初始化所有必填字段。

答案 1 :(得分:2)

如果从数据存储区加载实体,则不需要“实例化”该字段,因为它将从数据存储区加载(如果它存在于持久性中)。如果在persist()中集合为null,那么在检索它时,它可能也是null(因为这是使持久性机制透明的点)