我已将Hibernate配置为使用PostgreSQL序列(通过注释)为主键id列生成值,如下所示:
@Id
@SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence")
@Column(name="id", unique=true, nullable=false)
public int getId() {
return this.id;
}
Run Code Online (Sandbox Code Playgroud)
我在这个配置中看到的是,hibernate已经在持久化时分配了id值> 3000,而对使用过的序列的查询显示如下:
database=# select last_value from entity_id_seq;
last_value
------------
69
Run Code Online (Sandbox Code Playgroud)
(1排)
问题:
有什么不对吗?
hibernate应该与序列表同步吗?
如果没有,它在哪里存储最后生成的ID?
谢谢.
我真的很困惑......但首先,让我给你一个粗略的概述.
我已经在数据库中进行了一些重组,将4个表合并为两个.所有表都有简单的数字序列作为主键.事实上,这些表非常(非常)相似.它们被分成两部分的唯一原因是基于必须导入的历史数据.没有这种分裂,就会有很多冗余,从概念上讲它是有道理的.
现在,经过大量的工作进入数据清理后,现在终于可以将它们合并,只需使用其中一个字段作为鉴别器.谈论不那么抽象,表格包含公司.他们要么是当地居民,要么不是(两个班级).它们可以通过邮政编码(鉴别字段)轻松区分.这些表是缓慢变化的维度(序列是代理键).其他两个表包含附加到这些SCD的正常数据.因此,4桌.2为本地公司,2为非本地公司.
这些表现在已经简化和合并,所以我现在只有Company和CompanyData.
为了安全起见,并且不丢失任何历史信息,我创建了两个带有新序列字段的新表.旧的序列保存10年后我意识到出了问题;)
到现在为止还挺好.
重组相当容易,重新连接正确的条目也是一个明智的选择.接下来,我需要更新与此DB接口的应用程序,这是一项更多的工作,但仍然很容易.该应用程序使用JPA,使用EclipseLink 2.0 - 如上所述 - 一个PostgreSQL 9.0数据库.
这里出现了奇怪的部分:
当我尝试插入新公司时,我收到重复的密钥错误,说明已存在给定的ID.但这应该由序列对象处理......如果不是吗?
所以我做了一些挖掘.我可以验证后续的inerts确实返回了带有递增 ID的重复键错误.这意味着序列逻辑正常.唯一的问题是当前值太低.因此,对nextval(或JPA使用的任何内容)的调用将返回已存在的ID.
我在JPA-Entity中有以下内容:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "enterprise_id_seq")
@Column(name = "id", nullable = false)
private Integer id;
Run Code Online (Sandbox Code Playgroud)
我的序列看起来像这样:
test_db=# \d enterprise_id_seq
Sequence "public.enterprise_id_seq"
Column | Type | Value
---------------+---------+---------------------
sequence_name | name | enterprise_id_seq
last_value | bigint | 19659
start_value | bigint | 1
increment_by | bigint | 1
max_value | bigint | 9223372036854775807
min_value | bigint | …Run Code Online (Sandbox Code Playgroud)