【问题标题】:Hibernate, persisting ManyToMany休眠,坚持多对多
【发布时间】:2013-10-30 20:32:51
【问题描述】:

我正在尝试将添加内容持久化到与另一个实体具有多对多关系的实体中。

我的数据库是这样的:

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

实体工作正常,我可以看到正确的作者列表以及正确的书籍和作者。问题是书内的作者列表(作者内的书籍列表)没有更新,没有抛出任何异常。

我哪里做错了?

【问题讨论】:

    标签: java spring hibernate persistence


    【解决方案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);
    

    【讨论】:

    • 我接受你的回答,因为它让我觉得我没有合并书,所以我按照你的建议级联并使用 Spring 的注释 @Transactional。现在它可以正常工作了!
    【解决方案2】:

    在多对多注解中同时使用持久化和合并。

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

    【讨论】:

      猜你喜欢
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-08-28
      相关资源
      最近更新 更多