【问题标题】:JPA/Hibernate selective flushJPA/Hibernate 选择性刷新
【发布时间】:2011-11-22 09:50:07
【问题描述】:

我想我会开始

问题

有没有办法确保只有以某种方式明确“标记”的实体才会刷新到数据库中?

环境

我们正在使用 Java EE 5、Seam 2、JBoss AS 6 和 Hibernate(尽管我们尝试将直接的 Hibernate 依赖项保持在最低限度)。

目标

目前,我们有映射到瞬态 DTO 对象的实体,然后在业务层中使用这些实体并绑定到 facelets 以进行表示。当我们需要保存数据时,我们将 DTO 映射回实体并持久化它们。我想用包装实体的包装器业务对象替换 DTO,以便:

  • 不需要映射,因为业务对象将调用包装实体上的 getter 和 setter,而不是存储它自己的数据副本。
  • 在创建业务对象时可以指定提示,但如果未获取某些内容,则稍后可以根据 JPA 延迟自动获取。这是我最讨厌的。我讨厌每次需要时都必须手动获取额外的东西。它通常会导致“业务”代码过于复杂,尤其是当有大量数据并且预先获取所有数据太慢时。当我打电话给getRelatedStuff() 时,它应该就在那里
  • 保存就像“标记”相关业务对象并调用刷新一样简单(我正在考虑使用Seam conversation scoped transactions with manual flushing)。

问题

这种模式的问题在于 JPA 愿意并且渴望在刷新期间将所有内容刷新到数据库中。我宁愿明确告诉 JPA 我想要刷新哪些实体。任何我没有指定的都不应该被刷新。

作为第二个问题,这种模式是否是个好主意?

【问题讨论】:

    标签: hibernate jpa seam


    【解决方案1】:

    当然可以。

    打电话就行了

    em.clear();

    之前

    em.merge();

    这将导致任何对象被分离。 然后,您只需将要合并/保留的每个对象作为方法的参数传递。这只会将您想要的对象刷新到数据库中。

    请注意,在调用 em.clear() 之后,唯一持久化的对象将是合并/持久化的对象。

    【讨论】:

      【解决方案2】:

      不是个好主意。在 ORM 中,不刷新数据库更改的方法是不对对象进行更改。如果您需要对框架进行如此细粒度的控制,那么您就错了。使用 Hibernate,您的业务逻辑应该完全忘记某处有数据库。您将 Hibernate 视为 RDBMS 之上的一个层。相反,它更像是一个容量近乎无限的 Map,您可以在其中通过 id 存储和获取对象。与 Map 一样,当您从中获取对象并对对象进行更改时,这些更改也会反映在 Map 中,并且 Map 上的其他获取将看到更新的对象状态。当然,对于 Hibernate,更改必须发生在事务中,但考虑到这是一个内存事务,这是必需的,因为 Map 是由多个线程同时访问的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-28
        • 2019-07-10
        • 2020-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        相关资源
        最近更新 更多