8

I have a bidirectional one-to-many relationship. I'm trying to persist it like in this doc:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html#example-parentchild-bidir

Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
c.setParent(p);
p.getChildren().add(c);
session.save(c);
session.flush();

Is the flush() required there? What exactly does it do? I know what it does, but I discovered it costs me 100 ms and I would really like to avoid it if possible.

When session.load() or even session.refresh() is called and I hadn't flushed, will it include the new Child in the collection?

Konrad Garus
  • 53,145
  • 43
  • 157
  • 230

4 Answers4

12

The call to flush will synchronise the session state with the database. You do not need to explicitly flush at that point. Hibernate is clever enough to know when it needs to update the database with the session e.g. before executing a query.

That 100ms cost will have to be incurred at some point since it's an inevitable consequence of using a database in your application. Hibernate is able to delay this operation and batch up database changes to minimise round trips to the database.

Hibernate will flush the session when the transaction ends (by default) and so if you call load in the same session you will get the same object back from the session. If you call load in a new session Hibernate will have flushed the changes and your child will be in the collection.

If you were to clear the session or evict your object from the session before a flush was performed you would find that your child is not present.

This chapter from the docs should help.

Alex Barnes
  • 7,174
  • 1
  • 30
  • 50
5

flush is required if you want to guarantee that a different session will be able to see your changed data.

When session.load() or even session.refresh() is called and I hadn't flushed, will it include the new Child in the collection?

If you are in the same session and you call session.refresh, your manual changes will be lost. if you are in a different session and you call session.refresh, they will not include your manual changes.

Basanth Roy
  • 6,272
  • 5
  • 25
  • 25
1

If you want to do something "simple" and undoable but already are inside transaction, you can flush, do something that itself does not cause flushing and if you find out you don't want what you did, you can evict changed objects.

But this smells, but it can sometimes be the simplest thing that work (given some smelly code to begin with).

Alpedar
  • 1,314
  • 1
  • 8
  • 12
0

Flush will execute any pending SQL statements for entities previously marked for saving (i.e. save/create/merge/persist/delete/remove etc.).

One important thing this does is trigger DB constraint validation. So if you want/need to gracefully handle constraint violations as they happen (i.e. with the causing INSERT/UPDATE/DELETE) you need to flush after save/create/merge/persist/delete/remove.

Mirvnillith
  • 405
  • 5
  • 18