2014-02-13 71 views
2

我正在JPA中使用EclipseLink并调用EntityManager.merge()来插入/更新数据库中的记录。记录来自外部系统,所以我无法判断它们是新的还是现有的更新。如何判断JPA EntityManager.merge是否正在执行插入操作或更新

有没有什么办法可以知道当我打电话给merge()时JPA执行什么样的操作(插入/更新)?

+1

为了确保发生了什么,您可以启用jpa提供程序日志来查看sql查询。 – landal79

回答

1

首先,这种行为对你来说是透明的,所以在引擎盖下做什么合并不会直接告诉你。

但是由于您没有提供有关合并操作的详细信息,因此我很难想象您有哪些用例,哪些用户不知道是否更新或插入。在这方面的问题将是

  • 你使用生成或手动ID?
  • 你使用的版本列?
  • 您是插入/更新单个实体还是子实体?
+0

手动标识,没有版本列,只有单个实体。用例是第三方系统发送一个包含更新和新记录的json到我的REST应用程序,我需要标记新的和更新的记录,因为这个应用程序需要与另一个服务器保持同步。我在每个表中都有一个新的,更新和删除列,所以如果插入记录,我需要将new设置为true,如果更新,则将其更新为true。 – momo

+0

在这种情况下,我认为你所能做的就是通过ID选择每条记录,然后相应地设置你的标志列。 –

0

我也想回答这个问题。

我可以想象很多情况下,我需要检查对象是否存储新记录或现有记录的值。

为了缩短历史记录,我从外部来源(文件,REST,无论什么)获取记录,我需要知道何时将业务验证应用于某种形式,并在每种情况下也触发正确的操作。

在几篇文章中找到的默认解决方案是使用自动生成的ID字段。

当我有一个自动生成的ID我可以检查它的值是否为空(id在注册表包含中自动初始化,并在从数据库中获取数据时返回填充)。但是,如果我没有自动生成的ID,或者当它是注册表包含但其值已被应用程序或外部源非正确初始化时,此逻辑不适用(失败)。

我已经完成了对每个记录处理的数据库的查询,但是这会造成不必要的过多读取。

另一种方式(需要更多测试)是在称为isNew的实体中创建一个瞬态属性。在构造函数中使用true值初始化,在@PostLoad方法中使用false。当记录是新的时,构造函数会将对象标记为isNew = true;当它被读取时,@PostLoad将标记isN​​ew = false。

这可能是您的解决方案,或者有人可以告诉我们一个更好的方法来做这个验证。

相关问题