我有几个使用AUTO
密钥生成策略的实体Hibernate
和postgres
。
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
这将导致生成hibernate_sequence
,并且每个实体在分配密钥时都会使用该序列。
现在我有一个包含大量缓存数据(如100k条目)和一些用户表的表。由于两者都使用策略AUTO
,因此它们都从相同的休眠序列中获取密钥。因此,即使我只有10个用户,他们也会拥有6到7位数的ID,例如123123
。
我想知道,一般来说,是否应该为每个表引入自定义序列?或者我不应该关心那个id那么多吗?
答案 0 :(得分:9)
我最近为我的项目解决了这个问题。我使用增强序列生成器(这是序列式生成器的默认值)并将prefer_sequence_per_entity
参数设置为true
。
我package-info.java
的内容:
@GenericGenerator(
name = "optimized-sequence",
strategy = "enhanced-sequence",
parameters = {
@Parameter(name="prefer_sequence_per_entity", value="true"),
@Parameter(name="optimizer", value="hilo"),
@Parameter(name="increment_size", value="50")})
package org.example.model;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
在使用方面,您只需要
@Id @GeneratedValue(generator="optimized-sequence")
public long id;
我更喜欢单独的序列,因为我偶尔会删除一个表并重新创建它,我希望ID从一个开始。
答案 1 :(得分:1)
您可以将串行数据类型用于您的用户ID,或使用PostgreSQL序列。 喜欢:
digoal=# create table tt(id serial, info text);
CREATE TABLE
digoal=# insert into tt (info) values ('test'),('test');
INSERT 0 2
digoal=# select * from tt;
id | info
----+------
1 | test
2 | test
(2 rows)
OR
digoal=# create table tt1(id int, info text);
CREATE TABLE
digoal=# create sequence seq_tt1;
CREATE SEQUENCE
digoal=# alter table tt1 alter column id set default nextval('seq_tt1'::regclass);
ALTER TABLE
digoal=# insert into tt1 (info) values ('test'),('test');
INSERT 0 2
digoal=# select * from tt1;
id | info
----+------
1 | test
2 | test
(2 rows)
答案 2 :(得分:1)
尝试使用序列
首先在postgres
CREATE SEQUENCE YOUR_ENTITY_SEQ;
在实体中,将生成策略用作SEQUENCE
,并在下次将gen值分配集allocationSize
用于必要时
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "YOUR_ENTITY_SEQ")
@SequenceGenerator(name = "YOUR_ENTITY_SEQ", sequenceName = "YOUR_ENTITY_SEQ", allocationSize = 1)
private Long id;
答案 3 :(得分:0)
这只是Hibernate管理主键的首选方式。它将生成适当的SQL习惯用法,具体取决于您的底层数据库(Oracle的序列,DB2的身份密钥字段等)。
但是,如果您觉得它们更适合您的业务,则可以完美地定义复合键。有人在Stackoverflow中对此进行了很好的解释: