I have been working on Hibernate since sometime and I never really paid attention to the flush() method until yesterday.
I understand that flush() is invoked automatically when the transaction is committed.
I am working on a sample Library Management System. The relation between Authors and Books is ManyToMany
In Author.java
@Fetch(FetchMode.SELECT)
@ManyToMany(mappedBy="authors", cascade={CascadeType.PERSIST, CascadeType.MERGE})
private Set<Book> books = new HashSet<Book>();
In Book.java
@ManyToMany
@Cascade({org.hibernate.annotations.CascadeType.PERSIST})
@JoinTable(
name="BookAuthor",
joinColumns={@JoinColumn(name="bookId", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="authorId", referencedColumnName="id")}
)
private Set<Author> authors = new HashSet<Author>();
There is a mapping table BookAuthor in the database.
This is what I am doing.
- Set FlushMode to MANUAL
- Get a Book from the database
- Create a new Author. (Transient)
- Add author to the authors Set in the Book instance.
- Begin Transaction
- Update book instance
- Commit transaction.
Contrary to my expectation, I notice that updating the Book has NOT propagated and persisted the transient Author instance. The Author instance is still transient.
Now, if I set the FlushMode to AUTO(default), not only is the transient Author committed but a relation is also created in the BookAuthor table.
I am surprised to know that flush() has such an important role to play.
Am I doing something wrong?
Regards,
Shardul.