JPA / Hibernate选择性刷新

时间:2011-09-21 23:53:02

标签: hibernate jpa seam

我想我会从

开始

问题

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

环境

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

目标

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

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

问题

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

作为次要问题,这种模式是不是一个好主意?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

当然可以。

致电

  

em.clear();

之前

  

em.merge();

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

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