Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA OneToMany - Collection is null

I'm trying to set up a bidirectional relationship using JPA. I understand that it's the responsability of the application to maintain both sides of the relationship.

For example, a Library has multiple Books. In the Library-entity I have:

@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);
  }
  ..
}

The Book-entity is:

@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);
  }
  ..
}

Unfortunately, the collection at the OneToMany-side is null. So for example a call to setLibrary() fails because this.library.getBooks().contains(this) results in a NullPointerException.

Is this normal behavior? Should I instantiate the collection myself (which seems a bit strange), or are there other solutions?

like image 891
user3001511 Avatar asked Nov 17 '13 12:11

user3001511


1 Answers

Entities are Java objects. The basic rules of Java aren't changed just because there is an @Entity annotation on the class.

So, if you instantiate an object and its constructor doesn't initialize one of the fields, this field is initialized to null.

Yes, it's your responsibility to make sure that the constructor initializes the collection, or that all the methods deal with the nullability of the field.

If you get an instance of this entity from the database (using em.find(), a query, or by navigating through associations of attached entities), the collection will never be null, because JPA will always initialize the collection.

like image 127
JB Nizet Avatar answered Sep 28 '22 20:09

JB Nizet