Reputation: 3734
I'm trying to persist an addition to a list in an entity that have a many to many relationship with the other.
My database is like this:
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;
Those are the entities, 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
Author:
@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;
}
....
This is the getByID method of the book dao, the one for author is pretty much the same:
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;
}
And this is what i'm trying to do:
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);
The entities works fine, i can see the correct list of authors and correct book and author. The problem is that authors list inside book (And books list inside author) doesn't get updated, without throwing any exception.
Where am i doing wrong?
Upvotes: 1
Views: 237
Reputation: 199
USE both persist and merge in the ManyToMany Annotation.
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
Upvotes: 1
Reputation: 29693
You should set cascade
property to @ManyToMany
annotation
@ManyToMany::cascade()
@ManyToMany(mappedBy = "authors", cascade= CascadeType.ALL)
public List<Book> getBooks()
{
return books;
}
and
@ManyToMany(cascade= CascadeType.ALL)
public List<Author> getAuthors()
{
return authors;
}
Also you should call EntityManger::merge() on updated entity.
E.g.
em.merge(book);
Upvotes: 1