问题
I have two entities, Shelf and Book. A Shelf can have multiple Books (the relationship is bi-directional). I've exposed both of these as JpaRepositories.
Here's the issue:
- I create a shelf by posting { "name":"sci-fi" } to /shelves.(success)
- I create a book for that shelf by posting { "name":"mybook", "shelf":"localhost:8080/shelves/1" } to /books. (success)
- When I get the book I just created at /books/1, it has the correct link to the parent shelf.
- But when I go to shelves/1/books, I get an empty result, { }!
Any ideas what I might be missing?
Right now I've constructed a workaround by explicitly adding the book to its shelf in a beforeCreate event, but it seems like this should be totally unnecessary. (It does fix the problem, however.)
@HandleBeforeCreate(Book.class)
public void handleCreate(Book book) {
// why is this necessary?
book.getShelf().getBooks().add(book);
}
Here are the entity classes:
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@ManyToOne
private Shelf shelf;
public Shelf getShelf() {
return shelf;
}
public void setShelf(Shelf shelf) {
this.shelf = shelf;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book other = (Book) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
@Entity
public class Shelf {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@OneToMany
private List<Book> books = new ArrayList<Book>();
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Shelf other = (Shelf) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
I'm using Spring Boot 1.1.8.
回答1:
In your Shelf entity, add the mappedBy = "self"
property to the @OneToMany
annotation in books:
@OneToMany(mappedBy = "self")
private List<Book> books = new ArrayList<Book>();
This will auto populate the list of books with the books whose reference to self
matches.
回答2:
I think you need to update shelf to add new book you created as a last step. This is because you are using bi-directional relationship and shelf has no idea about books till you update it with the books it should hold.
来源:https://stackoverflow.com/questions/26805228/after-successfully-adding-child-entity-with-parent-reference-child-does-not-sho