2013-10-30 75 views
1

我試圖堅持一個列表中的另一個實體,與另一個多對多的關係。休眠,堅持ManyToMany

我的數據庫是這樣的:

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

    .... 

這是書道的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); 

的實體工作得很好,我可以看到作者和正確的書和作者的正確列表。問題在於書中的作者列表(和作者內部的書籍列表)沒有得到更新,沒有拋出任何異常。

我在哪裏做錯了?

回答

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

我接受你的答案,因爲它讓我覺得我不是合併書,所以我遵循你的建議來級聯並使用Spring的註釋@Transactional。現在它正常工作! –

1

USE在ManyToMany註解中都存在併合並。

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