代码之家  ›  专栏  ›  技术社区  ›  Behrang Saeedzadeh

在JPA中实例化集合字段是强制性的吗?

  •  3
  • Behrang Saeedzadeh  · 技术社区  · 14 年前

    @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。

    我认为jpa2中的情况发生了变化,现在JPA运行时使用运行时字节码增强或反射自动实例化字段,所以我又尝试了一次,但是如果不实例化 aProduct.getParts().add(aPart) 会抛出一个NPE。

    所以我的问题是,不实例化 部分

    2 回复  |  直到 14 年前
        1
  •  10
  •   Péter Török    14 年前

    我的理解是,JPA提供者只能在从DB加载的实体中正确地实例化字段。但是,如果创建新的(暂时的)实体,则必须确保所有字段都有效。请注意,Hibernate/JPA不知道新创建的临时实体,直到您将其实际附加到持久性上下文。如果你仔细想想,这是合乎逻辑的(至少对我来说):如果你依靠JPA/Hibernate来正确地实例化你的对象,你会建立一个强大的、侵入式的实现依赖关系,这会使你很难再在没有它的情况下工作。

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

        2
  •  2
  •   DataNucleus    14 年前

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