休眠应该为每个表使用唯一的序列吗?

时间:2014-04-11 07:27:54

标签: java sql hibernate postgresql

我有几个使用AUTO密钥生成策略的实体Hibernatepostgres

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

这将导致生成hibernate_sequence,并且每个实体在分配密钥时都会使用该序列。

现在我有一个包含大量缓存数据(如100k条目)和一些用户表的表。由于两者都使用策略AUTO,因此它们都从相同的休眠序列中获取密钥。因此,即使我只有10个用户,他们也会拥有6到7位数的ID,例如123123

我想知道,一般来说,是否应该为每个表引入自定义序列?或者我不应该关心那个id那么多吗?

4 个答案:

答案 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中对此进行了很好的解释:

How to map a composite key with Hibernate?