Hibernate,持久化ManyToMany

时间:2013-10-30 20:32:52

标签: java spring hibernate persistence

我正在尝试在与另一个有多对多关系的实体中坚持添加列表。

我的数据库是这样的:

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;

这些是实体,Book:

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

    ....

这是本书的getByID方法,作者的方法几乎相同:

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

实体工作正常,我可以看到正确的作者列表和正确的书籍和作者。问题在于作者在书中列出的内容(以及作者内部的书籍列表)没有得到更新,也没有任何例外。

我在哪里做错了?

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

USE在ManyToMany Annotation中保持并合并。

@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })