1

他のエンティティと多対多の関係を持つエンティティのリストへの追加を永続化しようとしています。

私のデータベースは次のようなものです:

CREATE TABLE book (
    isbn VARCHAR(20) PRIMARY KEY NOT NULL, 
    name VARCHAR(255)) ENGINE = InnoDB;
CREATE TABLE author (
    aid INT PRIMARY KEY NOT NULL AUTO_INCREMENT, 
    name VARCHAR(100)) ENGINE = InnoDB;
CREATE TABLE aubo (
    aid INT NOT NULL,
    isbn VARCHAR(20),
    PRIMARY KEY (aid, isbn),
    FOREIGN KEY (aid) REFERENCES author(aid) ON DELETE RESTRICT ON UPDATE CASCADE,
    FOREIGN KEY (isbn) REFERENCES book(isbn) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE = InnoDB;

それらは実体です、ブック:

@Entity
public class Book {
    private String isbn;
    private String name;
    private List<Author> authors;

    ....

    @javax.persistence.JoinTable(name = "aubo", catalog = "pwtest", schema = "", joinColumns =     @javax.persistence.JoinColumn(name = "isbn", referencedColumnName = "isbn", nullable = false), inverseJoinColumns = @javax.persistence.JoinColumn(name = "aid", referencedColumnName = "aid", nullable = false))
    @ManyToMany
    public List<Author> getAuthors() {
        return authors;
    }

    public void setAuthors(List<Author> authors) {
        this.authors = authors;
    }

    ....more including equals and hashcode

著者:

@Entity
public class Author {
    private int aid;
    private String name;
    private List<Book> books;

    @ManyToMany(mappedBy = "authors")
    public List<Book> getBooks() {
        return books;
    }

    public void setBooks(List<Book> books) {
        this.books = books;
    }

    ....

これは book dao の getByID メソッドです。author のメソッドはほとんど同じです。

private static final Class CLASS = Book.class;

/**
 * Gets an element from it's ID
 * @param id ID
 * @return Element
 */
@Transactional
public Book getByID(@NotNull String id) {
    Criteria criteria = sessionFactory.getCurrentSession().createCriteria(CLASS);
    criteria.add(Restrictions.eq("isbn", id));
    Book book = (Book) criteria.uniqueResult();
    return book;
}

そして、これは私がやろうとしていることです:

Book book = bookDAO.getByID(isbn);
if(book == null) throw new IllegalArgumentException("Book id:"+isbn+" not found.");
Author author = authorDAO.getByID(Integer.parseInt(aid));
if(author == null) throw new IllegalArgumentException("Author id:"+aid+" not found.");

List<Author> authors = book.getAuthors();
authors.add(author);
author.getBooks().add(book);

エンティティは正常に動作します。著者の正しいリストと正しい本と著者を確認できます。問題は、書籍内の著者リスト (および著者内の書籍リスト) が更新されず、例外がスローされないことです。

私はどこで間違っていますか?

4

2 に答える 2

1

ManyToMany アノテーションで persist と merge の両方を使用します。

@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
于 2013-10-30T21:01:45.400 に答える
1

cascadeプロパティを@ManyToMany注釈@ManyToMany::cascade()に設定する必要があります

@ManyToMany(mappedBy = "authors", cascade= CascadeType.ALL)
public List<Book> getBooks() 
{
   return books;
}  

@ManyToMany(cascade= CascadeType.ALL)
public List<Author> getAuthors() 
{
   return authors;
}

また、更新されたエンティティでEntityManger::merge()を呼び出す必要があります。
例えば

em.merge(book);
于 2013-10-30T20:40:39.017 に答える