在这种情况下是不是有必要调用 flush()(JPA 接口)?

Posted

技术标签:

【中文标题】在这种情况下是不是有必要调用 flush()(JPA 接口)?【英文标题】:Is it necessary to call a flush() (JPA interface) in this situation?在这种情况下是否有必要调用 flush()(JPA 接口)? 【发布时间】:2010-10-31 06:28:06 【问题描述】:

因为调用 flush() 来让每个实体从内存持久化到数据库。因此,如果我调用过多不必要的 flush(),可能会花费很多时间,因此对于性能来说不是一个好的选择。这是一个我不知道什么时候调用flush()的场景?

//Order and Item have Bidirectional Relationships
Order ord = New ord("my first order");
Item item = New Item("tv",10);

//...process item and ord object

em.persist(ord);//em is an instance of EntityManager
em.flush();// No.1 flush()

item.setOrder(ord);
em.persist(item);

Set<Item> items= new HashSet<Item>();
items.add(item);
ord.setItems(items);

em.flush();// No.2 flush()

我的问题是:跟注一号同花是否可以避免?

我担心的是:为了执行 item.setOrder(ord),我们需要一个 ord 的数据库 id。并且只调用 em.persist(ord) 无法生成数据库 id,所以我必须在 item.setOrder(ord) 之前调用 em.flush() 。那么各位小伙伴们有什么看法呢?

提前致谢。

【问题讨论】:

【参考方案1】:

我应该先构建结构,然后坚持一切。

Order ord = New ord("my first order");
Item item = New Item("tv",10);

item.setOrder(ord);

Set<Item> items= new HashSet<Item>();
items.add(item);
ord.setItems(items);

em.persist(ord);

通过这种方式,您可以在一次调用中持久化整个树并且不需要刷新。

在良好的对象设计中,您应该使用 duffymo 描述的方式来连接您的对象。

【讨论】:

谢谢萨兰杜尔!是的,我想我可以在瞬态状态下构建对象并保持父级(如果在映射文件中,子级集合被设置为级联)。最后我可以做flush()。 你说flush()不是必须的吗?【参考方案2】:

我认为您应该在事务环境中执行所有这些操作,并让它为您处理这些问题。

您需要在对象中嵌入双向关系:

class Parent

    private List<Child> children;

    public boolean addChild(Child c)
    
        c.setParent(this); // this is the key piece

        return this.children.add(c);
    


class Child

   private Parent parent;

   public void setParent(Parent p)
   
      this.parent = p;
   

【讨论】:

谢谢,你是对的!并且您嵌入的双向关系现在可以使我的代码清晰!

以上是关于在这种情况下是不是有必要调用 flush()(JPA 接口)?的主要内容,如果未能解决你的问题,请参考以下文章

Stream.Dispose 是不是总是调用 Stream.Close(和 Stream.Flush)

Hibernate session.flush() 使用

在这种方法调用和传入参数的情况下,Java 评估顺序是不是得到保证

调用 Hibernate 会话刷新

在这种情况下是否有必要关闭StringReader?

Doctrine2 刷新单个删除的实体