Hibernate:我是否需要flush()?

时间:2011-09-12 12:24:54

标签: java hibernate transactions

我有双向的一对多关系。我试图像在这个文档中那样坚持它:

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();

那里需要flush()吗?它到底是做什么用的?我知道它做了什么,但我发现它花了我100毫秒,如果可能我真的想避免它。

当调用session.load()甚至session.refresh()并且我没有刷新时,它会在集合中包含新的Child吗?

4 个答案:

答案 0 :(得分:12)

对flush的调用将使会话状态与数据库同步。此时您无需显式刷新。 Hibernate非常聪明,可以知道何时需要使用会话更新数据库,例如在执行查询之前。

由于在应用程序中使用数据库是不可避免的后果,因此必须在某一时刻产生100毫秒的成本。 Hibernate能够延迟此操作并批量处理数据库更改,以最大限度地减少到数据库的往返。

Hibernate将在事务结束时刷新会话(默认情况下),因此如果在同一会话中调用load,您将从会话中获取相同的对象。如果您在新会话中调用load,Hibernate将刷新更改,您的孩子将在该集合中。

如果您在执行同花顺序之前清除会话或从会话中逐出您的对象,您会发现您的孩子不在场。

文档中的

This章节应该有所帮助。

答案 1 :(得分:5)

如果您想要保证其他会话能够看到您更改的数据,则需要

flush。

  

调用session.load()或者session.refresh()时,我没有   脸红了,它会在集合中包含新的孩子吗?

如果您在同一会话中并且调用session.refresh,则手动更改将丢失。如果您在不同的会话中并且调用session.refresh,它们将不包括您的手动更改。

答案 2 :(得分:1)

如果你想做一些“简单”和可撤销的事情,但已经在事务内部,你可以冲洗,做一些本身不会引起冲洗的事情,如果你发现你不想要你所做的事情,你可以逐出改变对象。

但这有点味道,但它有时可能是最简单的工作(给出一些有臭味的代码)。

答案 3 :(得分:0)

Flush将为之前标记为保存的实体执行任何挂起的SQL语句(即save / create / merge / persist / delete / remove等)。

其中一个重要事情是触发数据库约束验证。 因此,如果您希望/需要优雅地处理发生的约束违规(即导致INSERT / UPDATE / DELETE),您需要在save / create / merge / persist / delete / remove之后进行刷新。