I have three tables in my database; an Author table, which has an id column, a Publisher table, which has an id column, and a Book table, which has an id column, an authorId foreign key column, to the Author id, and a publisherId foreign key column,to the Publisher id. The foreign key on update/on delete options are all set to ‘NO ACTION’, but from what I understand, Hibernate should be able to handle these itself.
The Author entity has a set of Books, which contain the publisher Id, but do not know about the Author. I’ve set this up as follows:
@Entity
@Table(name="author")
public class Author {
private Integer id;
private Set<Book> books;
@Id @GeneratedValue
public Integer getId() {
return id;
}
@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL) {
@JoinColumn(name="authorId")
public Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}
@Entity
@Table(name="book") {
private Integer id;
private Integer publisherId;
@Id @GeneratedValue
public Integer getId() {
return id;
}
@ManyToOne(FetchType.EAGER)
@JoinColumn(name="publisherId")
public Integer getPublisherId() {
return publisherId;
}
public void setPublisherId(Integer publisherId) {
this.publisherId = publisherId;
}
}
My problem is that when I attempt to delete a Book from the Author’s set of books, Hibernate tries to update the authorId foreign key to null, and I get the error that the column authorId cannot be null in the Book table. What I want to happen is for that row to be deleted entirely.
I have also tried to add ‘orphanRemoval=true’ to the OneToMany annotation, and set on update/on delete to Cascade, but I get the same error.
Which annotations can I use to indicate that when a book is removed from the Author’s set of books, I want that row in the Book table to be removed? Is this possible at all with how I have my relationships set up and, if not, what is a better way to approach this?
In the database is the AuthorId column set to NOT NULL? It could be that Hibernate is going to delete the row in two passes. The first pass nulls the foreign key reference, the second pass then deletes the row. I’m using NHibernate and have certainly seen similar behaviour. If this is the case, then you should be able to sort your problem out by setting the AuthorId to be NULLable.