【问题标题】:Mixed surrogate composite key insert in JPA 2.0, PostgreSQL and Hibernate 3.5JPA 2.0、PostgreSQL 和 Hibernate 3.5 中的混合代理复合键插入
【发布时间】:2010-05-01 12:37:55
【问题描述】:

首先,我们使用 JPA 2.0 和 Hibernate 3.5 作为 PostgreSQL 数据库上的持久性提供程序。

我们通过 JPA 2.0 注释成功地将数据库序列用作单字段代理键的自动生成值,并且一切正常。

现在我们正在实现一个双时态数据库方案,该方案需要以下方式的混合键:

Table 1:
id             (pk, integer, auto-generated-sequence)
validTimeBegin (pk, dateTime)
validTimeEnd   (dateTime)
firstName      (varChar)

现在我们遇到了问题。你看,如果我们INSERT 一个新元素,id 字段是自动生成的,这很好。只是,如果我们想 UPDATE 这个方案中的字段,那么我们必须更改 validTimeBegin 列而不更改 id 字段并将其作为新行插入,如下所示:

在更新行之前:

|---|-------------------------|-------------------------|-------------------|
| id|      validTimeBegin     |       validTimeEnd      |     firstName     |
|---|-------------------------|-------------------------|-------------------|
|  1| 2010-05-01-10:00:00.000 |                    NULL |            Gerald |
|---|-------------------------|-------------------------|-------------------|

在 2010-05-01-10:35:01.788 服务器时间发生的行更新之后:

(we update the person with the id:1 to reflect his new first name...)
|---|-------------------------|-------------------------|-------------------|
| id|      validTimeBegin     |       validTimeEnd      |     firstName     |
|---|-------------------------|-------------------------|-------------------|
|  1| 2010-05-01-10:00:00.000 | 2010-05-01-10:35:01.788 |            Gerald |
|---|-------------------------|-------------------------|-------------------|
|  1| 2010-05-01-10:35:01.788 |                    NULL |             Jerry |
|---|-------------------------|-------------------------|-------------------|

所以我们的问题是,对于字段id 使用自动生成的序列根本不起作用,因为在插入新行时,ID 总是自动生成的,尽管它确实是组合键有时应该表现不同。

所以我的问题是: 有没有办法通过 JPA 告诉休眠停止自动生成id-字段,以防我想生成同一个人的新品种并在其他情况下照常继续,或者我必须接管使用自定义代码生成整个 id?

提前致谢, 杰拉德

【问题讨论】:

    标签: java jpa sequence composite-key surrogate-key


    【解决方案1】:

    所以...现在已经过去了一段时间没有任何 cmets,现在我很确定没有办法做到这一点。事实上,这也是开发人员开始在应用程序端通过自己的 id-generators 为数据库生成自己的唯一密钥的原因之一。 这样,数据库甚至都不知道代理键之类的东西;它只是接收它。

    顺便说一句: 我们通过实现我们自己的方法来更新这些行来解决我们的问题。这些方法现在是 OR-Mapper 依赖的,绝不符合 JPA 2.0,但 JPA 只是不支持此类行为的注释。

    【讨论】:

      【解决方案2】:

      AFAIK 您的 ID 字段不是 Hibernate 理解的 ID。如果我可以提出另一个解决方案,考虑到本质上您只想实现数据库修改日志记录:

      • 步骤 0:在 Hibernate 中仅使用 ID 作为主键。在 Postgres 中使用复合主键。
      • 第 1 步:将过滤器添加到休眠状态,以自动过滤所有设置了 validEndTime 的行。
      • 第 2 步:将自定义更新语句添加到 hibernate,它会执行插入操作。
      • 第 3 步:在 PostgreSQL 中添加自动设置结束时间的触发器。
      • 第 4 步:在 postgres 上创建一个约束索引,以便通过 hibernate 更快地查找。

      【讨论】:

      • 首先,感谢您的回答。这是解决问题的完全不同的方法。但是,我们必须使用 JPA2.0 并且没有我可以找到的过滤器构造,我不喜欢数据库触发器,因为它们是我必须维护的代码,它不在我的 IDE 中并且不告诉休眠我有一个化合物key 并不能解决生成的 id 的问题,而这正是问题所在。不过,从技术上讲,您所描述的这种方法对我来说是完全有效且可以的。我只是不明白这是如何解决问题的。
      猜你喜欢
      • 1970-01-01
      • 2021-10-14
      • 2015-09-28
      • 1970-01-01
      • 2012-01-06
      • 2011-11-22
      • 2020-02-19
      • 1970-01-01
      • 2011-02-09
      相关资源
      最近更新 更多