Question

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.

  1. Set FlushMode to MANUAL
  2. Get a Book from the database
  3. Create a new Author. (Transient)
  4. Add author to the authors Set in the Book instance.
  5. Begin Transaction
  6. Update book instance
  7. 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.

Était-ce utile?

La solution

flush is the method that writes changes to the database. Without flushing, nothing is written. So obviously, if you set flush mode to manual and never call flush, nothing will be written to the database.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top