Spring JPA - 删除一对多关系中的子项
Spring JPA - Delete Child in One-toMany relationship
我有以下作者 class:
@Entity
public class Author implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@JoinTable(
name="author_book",
joinColumns = @JoinColumn( name="author_id"),
inverseJoinColumns = @JoinColumn( name="book_id")
)
private Set<Book> books= new HashSet<Book>();
public Author() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}
我还有以下图书实体:
@Entity
public class Book implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
public Book() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
接下来,我有以下两个存储库:
public interface BookRepository extends CrudRepository<Book, Long> {
}
public interface AuthorRepository extends CrudRepository<Author, Long>{
}
最后,我有以下测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class AuthorRepositoryIntegrationTests {
@Autowired
AuthorRepository authorRepository;
@Autowired
BookRepository bookRepository;
@Test
@Transactional
public void deleteBookFromAuthor() {
Book book= new Book();
Author author= new Author();
author.getBooks().add(book);
author=this.authorRepository.save(author);
Iterable<Author> authors = this.authorRepository.findAll();
author=authors.iterator().next();
book=author.getBooks().iterator().next();
this.bookRepository.delete(book);
authors = this.authorRepository.findAll();
assertEquals(authors.iterator().next().getBooks().size(),0);
}
}
我的问题是这个测试用例中的最后一个断言失败了。如果我向作者添加一本书,它会自动添加到图书存储库中。但是,如果我从存储库中删除一本书,我该如何从作者那里删除它?
重做:好的,抱歉,我没有仔细看你的问题。答案虽然很简单,但这次我真的试过了。您需要从 POJO 中的父项中删除子项并重新保存没有子项的父项。请参阅下面的注释代码:
List<Book> books = new ArrayList<Book>();
Book book = new Book();
books.add(book);
Author author = new Author();
author.setBooks(books);
authorRepository.save(author);
Author a =authorRepository.findAll().iterator().next();
Book b = a.getBooks().get(0);
bookRepository.delete(b);
// REMOVE FROM PARENT
a.getBooks().remove(0);
authorRepository.save(a);
a = authorRepository.findAll().iterator().next();
System.out.println(a);
编辑:如果您担心一致性,您应该担心,只需从作者 POJO 中删除该书,当您保存作者时,cascade=CascadeType.ALL
将为您传播删除该书。例如:
Author a =authorRepository.findAll().iterator().next();
a.getBooks().remove(0);
authorRepository.save(a);
// NO BOOK
a = authorRepository.findAll().iterator().next();
System.out.println(a);
我有以下作者 class:
@Entity
public class Author implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@JoinTable(
name="author_book",
joinColumns = @JoinColumn( name="author_id"),
inverseJoinColumns = @JoinColumn( name="book_id")
)
private Set<Book> books= new HashSet<Book>();
public Author() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}
我还有以下图书实体:
@Entity
public class Book implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
public Book() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
接下来,我有以下两个存储库:
public interface BookRepository extends CrudRepository<Book, Long> {
}
public interface AuthorRepository extends CrudRepository<Author, Long>{
}
最后,我有以下测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class AuthorRepositoryIntegrationTests {
@Autowired
AuthorRepository authorRepository;
@Autowired
BookRepository bookRepository;
@Test
@Transactional
public void deleteBookFromAuthor() {
Book book= new Book();
Author author= new Author();
author.getBooks().add(book);
author=this.authorRepository.save(author);
Iterable<Author> authors = this.authorRepository.findAll();
author=authors.iterator().next();
book=author.getBooks().iterator().next();
this.bookRepository.delete(book);
authors = this.authorRepository.findAll();
assertEquals(authors.iterator().next().getBooks().size(),0);
}
}
我的问题是这个测试用例中的最后一个断言失败了。如果我向作者添加一本书,它会自动添加到图书存储库中。但是,如果我从存储库中删除一本书,我该如何从作者那里删除它?
重做:好的,抱歉,我没有仔细看你的问题。答案虽然很简单,但这次我真的试过了。您需要从 POJO 中的父项中删除子项并重新保存没有子项的父项。请参阅下面的注释代码:
List<Book> books = new ArrayList<Book>();
Book book = new Book();
books.add(book);
Author author = new Author();
author.setBooks(books);
authorRepository.save(author);
Author a =authorRepository.findAll().iterator().next();
Book b = a.getBooks().get(0);
bookRepository.delete(b);
// REMOVE FROM PARENT
a.getBooks().remove(0);
authorRepository.save(a);
a = authorRepository.findAll().iterator().next();
System.out.println(a);
编辑:如果您担心一致性,您应该担心,只需从作者 POJO 中删除该书,当您保存作者时,cascade=CascadeType.ALL
将为您传播删除该书。例如:
Author a =authorRepository.findAll().iterator().next();
a.getBooks().remove(0);
authorRepository.save(a);
// NO BOOK
a = authorRepository.findAll().iterator().next();
System.out.println(a);