我有双向的一对多关系。我试图像在这个文档中那样坚持它:
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
吗?
答案 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之后进行刷新。