@Entity
@SuppressWarnings("serial")
public class Author extends CommonVersionEntity {
private Set<Book> bookSet = new HashSet<Book>();
@ManyToMany
@JoinTable(name = "author_book", joinColumns = {
@JoinColumn(name = "author_id")
}, inverseJoinColumns = {
@JoinColumn(name = "book_id")
}, uniqueConstraints = @UniqueConstraint(columnNames = {
"author_id", "book_id"
}))
@ForeignKey(name = "author_book_fk", inverseName = "book_author_fk")
public Set<Book> getBookSet() {
return bookSet;
}
public void setBookSet(Set<Book> bookSet) {
this.bookSet = bookSet;
}
}
@Entity
@SuppressWarnings("serial")
public class Book extends CommonVersionEntity {
private Set<Author> authorSet = new HashSet<Author>();
@ManyToMany(mappedBy = "bookSet")
public Set<Author> getAuthorSet() {
return authorSet;
}
public void setAuthorSet(Set<Author> authorSet) {
this.authorSet = authorSet;
}
}
Author 是 owner side,Book 是 inverse side,join table 為 author_book。
遇到的問題是,當直接刪除一筆 Book 時,會發生以下的 error:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`db`.`author_book`, CONSTRAINT `book_author_fk` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`))
簡單說,就是因為 Book 是 inverse side ,所以對 Book 做的任何操作都不會反應到 Author 與 Book 的關聯上,也就是 join table author_book,所以導致 author_book上的 book_author_fk 發出抗議,因為 Book 被刪除,而該 Book id 還留在 author_book 上。
如果單純將 Author 上的 @ForeignKey 拿掉,那會造成 Book 順利刪除,但是該 Book id 還留在 author_book 上,導致下次載入 Author 時發生錯誤,當然可以將錯就錯的在 public Set<Book> getBookSet() { ... } 加上 @NotFound(action = NotFoundAction.IGNORE) 來迴避這樣的問題,唯一的後果就是在 author_book 留下一堆垃圾資料。
不然就是得在刪除 Book 時多做一些事情:
Book obj = this.getBook(id);
for (Author author : obj.getAuthorSet()) {
author.getBookSet().remove(obj);
}
this.getHibernateTemplate().delete(obj);將 Book 的每位 Author 找出來,再從 Author 這個 owner side 去移除與該 Book 的關聯。
沒有留言:
張貼留言