JPA OneToMany - Collection为null

时间:2013-11-17 12:42:01

标签: java jpa nullpointerexception

我正在尝试使用JPA建立双向关系。我理解应用程序的责任是维护关系的双方。

例如,图书馆有多本图书。在图书馆实体我有:

@Entity
public class Library {
  ..
  @OneToMany(mappedBy = "library", cascade = CascadeType.ALL)
  private Collection<Book> books;

  public void addBook(Book b) {
    this.books.add(b);
    if(b.getLibrary() != this)
      b.setLibrary(this);
  }
  ..
}

图书实体是:

@Entity
public class Book {
  ..
  @ManyToOne
  @JoinColumn(name = "LibraryId")
  private Library library;

  public void setLibrary(Library l) {
    this.library = l;
    if(!this.library.getBooks().contains(this))
      this.library.getBooks().add(this);
  }
  ..
}

不幸的是,OneToMany端的集合为空。因此,例如,对setLibrary()的调用失败,因为this.library.getBooks()。contains(this)会导致NullPointerException。

这是正常行为吗?我应该自己实例化这个集合(这看起来有点奇怪),还是有其他解决方案?

3 个答案:

答案 0 :(得分:7)

实体是Java对象。 Java的基本规则不会因为类上有@Entity注释而改变。

因此,如果您实例化一个对象并且其构造函数未初始化其中一个字段,则此字段将初始化为null。

是的,您有责任确保构造函数初始化集合,或者所有方法都处理字段的可为空性。

如果从数据库中获取此实体的实例(使用em.find(),查询或通过附加实体的关联导航),该集合将永远不会为null,因为JPA将始终初始化集合。

答案 1 :(得分:6)

似乎没有启动Library类中的Collection类型的书籍类型。它是null;

所以当类addBook方法将book对象添加到集合中时。它会导致NullPointerException。

@OneToMany(mappedBy = "library", cascade = CascadeType.ALL)
 private Collection<Book> books;

 public void addBook(Book b) {
    this.books.add(b);
    if(b.getLibrary() != this)
    b.setLibrary(this);
 }

启动它并试一试。

更改

private Collection<Book> books;

private Collection<Book> books = new ArrayList<Book>();

答案 2 :(得分:1)

尝试在OneToMany端将fetch类型关联属性设置为eager。实际上,您可以将此部分(this.library.getBooks()。add(this))留在会话中:

Library l = new Library();    
Book b = new Book();
b.setLibrary(l);
l.getBooks().add(b);