JPA 2.0、PostgreSQL 和 Hibernate 3.5 中的混合代理复合键插入
首先,我们使用 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 告诉 hibernate 停止自动生成 id 字段,如果我想生成同一个人的新品种,并在其他情况下照常进行,或者做我必须用自定义代码接管整个 id 生成?
提前致谢, 杰拉德
First off, we are using JPA 2.0 and Hibernate 3.5 as persistence provider on a PostgreSQL database.
We successfully use the sequence of the database via the JPA 2.0 annotations as an auto-generated value for single-field-surrogate-keys and all works fine.
Now we are implementing a bi-temporal database-scheme that requires a mixed key in the following manner:
Table 1:
id (pk, integer, auto-generated-sequence)
validTimeBegin (pk, dateTime)
validTimeEnd (dateTime)
firstName (varChar)
Now we have a problem. You see, if we INSERT
a new element, the field id
is auto-generated and that's fine. Only, if we want to UPDATE
the field within this scheme, then we have to change the validTimeBegin
column WITHOUT changing the id
-field and insert it as a new row like so:
BEFORE THE UPDATE OF THE ROW:
|---|-------------------------|-------------------------|-------------------|
| id| validTimeBegin | validTimeEnd | firstName |
|---|-------------------------|-------------------------|-------------------|
| 1| 2010-05-01-10:00:00.000 | NULL | Gerald |
|---|-------------------------|-------------------------|-------------------|
AFTER THE UPDATE OF THE ROW happening at exactly 2010-05-01-10:35:01.788 server-time:
(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 |
|---|-------------------------|-------------------------|-------------------|
So our problem is, that this doesn't work at all using an auto-generated-sequence for the field id
because when inserting a new row then the id ALWAYS is auto-generated although it really is part of a composite key which should sometimes behave differently.
So my question is:
Is there a way to tell hibernate via JPA to stop auto-generating the id
-field in the case I want to generate a new variety of the same person and go on as usual in every other case or do I have to take over the whole id-generation with custom code?
Thanks in advance,
Gerald
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所以... 一段时间过去了,没有任何评论,现在我很确定没有办法做到这一点。事实上,这就是开发人员开始通过应用程序端自己的 id 生成器为数据库生成自己的唯一密钥的原因之一。
这样数据库就永远不会知道代理键这样的东西;它只是接收它。
顺便一提:
我们通过实现我们自己的方法来更新这些行的任务来解决我们的问题。这些方法现在依赖于 OR-Mapper,并且绝不符合 JPA 2.0,但 JPA 只是不支持此类行为的注释。
So... Some time has passed now without any comments and now I'm pretty sure that there's no way to do that. In fact it's one of the reasons why developers start generating their own unique keys for databases via their own id-generators on the application-side.
This way the database never even knows about such a thing as a surrogate key; It just receives it.
By the way:
We solved our problem by implementing our own methods for the task of updating such rows. These methods now are OR-Mapper dependent and in no way JPA 2.0 compliant but JPA just doesn't support an annotation for such behavior.
AFAIK 你的 ID 字段不是 Hibernate 理解的意义上的 ID。如果我可以提出另一种解决方案,考虑到本质上您只想实现数据库修改日志记录:
AFAIK your ID field is not an ID in the sense as Hibernate understands it. If I might propose another solution, given the fact that essentially you just want to realize database modification logging: