Java JPA OneToMany - 集合为空
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20030771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA OneToMany - Collection is null
提问by user3001511
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.
我正在尝试使用 JPA 建立双向关系。我理解维护双方关系是申请的责任。
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:
Book实体是:
@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.
不幸的是,OneToMany 端的集合为空。例如,调用 setLibrary() 失败,因为 this.library.getBooks().contains(this) 导致 NullPointerException。
Is this normal behavior? Should I instantiate the collection myself (which seems a bit strange), or are there other solutions?
这是正常行为吗?我应该自己实例化集合(这看起来有点奇怪),还是有其他解决方案?
采纳答案by JB Nizet
Entities are Java objects. The basic rules of Java aren't changed just because there is an @Entity
annotation on the class.
实体是 Java 对象。Java 的基本规则不会因为@Entity
类上有注释而改变。
So, if you instantiate an object and its constructor doesn't initialize one of the fields, this field is initialized to null.
因此,如果您实例化一个对象并且其构造函数没有初始化其中一个字段,则该字段将被初始化为 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.
如果您从数据库中获取此实体的实例(使用 em.find()、查询或通过浏览附加实体的关联),则该集合永远不会为空,因为 JPA 将始终初始化该集合。
回答by MouseLearnJava
It seems that books type of Collection in Library class is not initilized. It is null;
似乎 Library 类中的 Collection 类型没有初始化。为空;
So when class addBook method to add a book object to collection. It cause NullPointerException.
所以当类 addBook 方法将书对象添加到集合时。它会导致 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);
}
Initilize it and have a try.
初始化它并尝试一下。
Change
改变
private Collection<Book> books;
To
到
private Collection<Book> books = new ArrayList<Book>();
回答by tmarwen
Try to set the fetch type association property to eager on the OneToMany side. Indeed, you may leave this part (this.library.getBooks().add(this)) to be written within a session:
尝试在 OneToMany 端将 fetch 类型关联属性设置为eager。实际上,您可以将这部分 (this.library.getBooks().add(this)) 留在会话中:
Library l = new Library();
Book b = new Book();
b.setLibrary(l);
l.getBooks().add(b);