簡體   English   中英

刪除 @ManyToMany 關聯時出現 ConcurrentModificationException Spring 數據 Jpa

[英]ConcurrentModificationException when deleting a @ManyToMany associations Spring Data Jpa

i'm getting crazy with this... I followed all articles from Thoughts on Java and Vlad mihalcea about mapping associations in hibernate, but i don't know why deleting in @ManyToMany, is somehow always messed up in my project about Rest services與 Spring 數據 Jpa。

我有一本基本的書->作者多多關系,我認為我正確地映射了(至少根據他們在引用較高的兩個參考文獻中的推薦方式)。

我重寫了equals和hashcode,我編寫並使用這些方法來管理實體之間的關聯,但是當我嘗試從作者那里刪除書籍(我想刪除)時,我得到了一個ConcurrentModificationException:null,即使我使用了一個迭代器.

我的實體:

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Size( min = 2, max = 30)
    @Column (length = 30)
    private String firstName;

    @Size( min = 2, max = 30)
    @Column (length = 30)
    private String lastName;

    @ManyToMany(mappedBy = "authors")
    private Set<Book> books = new HashSet<>();

    public Author(@NotNull @Size(min = 2, max = 30) String firstName, @NotNull @Size(min = 2, max = 30) String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void addBook(Book book){
        this.books.add(book);
        book.getAuthors().add(this);
    }

    public void removeBook(Book book){
        this.books.remove(book);
        book.getAuthors().remove(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        if (this.getClass() != o.getClass()) return false;
        return id != null && id.equals(((Author)o).getId());
    }
    @Override
    public int hashCode() {
        return 17;
    }
}

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String isbn;
    @NotNull
    private String title;

    //Owning side
    @NotNull
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "book_author",
               joinColumns = @JoinColumn(name = "book_id"),
               inverseJoinColumns = @JoinColumn(name = "author_id"))
    private Set<Author> authors = new HashSet<>();

    public Book(String title) {
        this.title = title;
        this.isbn = RandomStringUtils.randomAlphanumeric(10);
    }

    public void addAuthor(Author author){
        this.authors.add(author);
        author.getBooks().add(this);
    }

    public void removeAuthor(Author author){
        this.authors.remove(author);
        author.getBooks().remove(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        if (this.getClass() != o.getClass()) return false;
        return id != null && id.equals(((Book)o).getId());
    }
    @Override
    public int hashCode() {
        return 13;
    }
}

我的業務層中的刪除方法:


    public void deleteAuthor(Long id) {
        Optional<Author> author = authorRepository.findById(id);
        if (author.isPresent()){
            Author au = author.get();
            for (Book book : au.getBooks()) {
                au.removeBook(book);
            }
            authorRepository.delete(au);
        }
    }

在 for each 的第一個循環之后我有異常。 它的編寫與示例中的完全相同,所以我完全不知道。 我想知道是不是 Spring 數據層讓它變得更復雜了? 謝謝你的幫助 !

編輯:僅當我的作者擁有不止一本書時才會出現異常

顯然我設法通過在迭代時添加一個新的 hash 集來解決這個問題。

    public void deleteAuthor(Long id) {
        Optional<Author> author = authorRepository.findById(id);
        if (author.isPresent()) {
            for (Book book : new HashSet<Book>(author.get().getBooks())) {
                author.get().removeBook(book);
            }
            authorRepository.delete(author.get());
        }
    }

但奇怪的是我必須這樣做,在我看到的所有例子中,沒有這樣的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM