2016-03-05 1 views
0

Я следующий класс Автор:Spring JPA - Удаление ребенка в одной-toMany отношений

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

Вопрос в том, что последнее утверждение в этом случае не выполняется. Если я добавлю книгу автору, она автоматически добавится в репозиторий книг. Но если я удалю книгу из репозитория, как мне удалить ее от авторов?

ответ

0

REDO: Хорошо, извиняюсь, я не достаточно внимательно подошел к вашему вопросу. Ответ хотя и достаточно прост, и на этот раз я действительно попробовал. Вам нужно удалить дочерний элемент из родителя в 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); 

EDIT: Если вы беспокоитесь о последовательности, которую вы должны быть, просто удалите книгу от автора 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); 
+0

Спасибо за вход. Он этого не делал. Я добавил getTransaction() и commit() прямо перед последним findAll(). Все равно получается getBooks(). Size() == 1. – Klaus

+0

См. REDO выше. –

+0

ОК. Таким образом, вы удаляете из bookRepository и удаляете из коллекции. Моя забота действительно должна быть удалена в двух местах. Поскольку, если я удаляю только в bookRepository, это оставляет мою базу данных непоследовательными, поскольку автор будет ссылаться на несуществующие книги. Думаю, есть какая-то комбинация аннотаций, которая позволяет мне предотвратить это? – Klaus

0

если вы используете JPA добавить один ко многим отношений orphanRemoval=true еще для спящего режима CascadeType.DELETE_ORPHAN

+0

Извините. Не помогло. Я добавил orphanRemoval = true для объявления Person-to-many Person. Я предполагаю, что это то, что вы имели в виду. – Klaus

+0

orphanRemoval - это когда сначала удалять дочерние элементы, а затем удалять основную запись –

Смежные вопросы