Hibernate和PostgreSQL:我可以配置GenerationType.IDENTITY,其中每个id列的默认值来自共享序列吗?

时间:2013-02-17 17:08:47

标签: java hibernate hibernate-annotations

好的,我不是百分百确定我是否真的想要这个,但目前这似乎是一个好主意。

我像这样配置我的实体:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id = 0;

如果我让Hibernate生成表,结果是:

  id bigserial NOT NULL,
  CONSTRAINT test_pkey PRIMARY KEY (id)

bigserial又转换为bigint,默认值为:

nextval('test_id_seq'::regclass)

现在没关系,但我正在考虑对所有表使用单个序列,并希望默认值为:

nextval('my_global_sequence'::regclass)

也许我可以稍后手动调整默认值,但你有什么想法我怎么能告诉hibernate自动定义这样的表?有没有办法推动我自己的create table sql策略,它会为id列发出这样的代码(未经测试的SQL语法):

id bigint NOT NULL DEFAULT = nextval('my_global_sequence'::regclass)

请注意,我想坚持使用IDENTITY策略,因为我想避免任何“hi / lo乘法分配大小缓存序列,无论什么”-strategies。我不时需要通过pgAdmin插入一些手动行,而不会冒任何与hibernate的id冲突的风险。所有其他策略对我来说都是魔术(=我不理解它们)。

2 个答案:

答案 0 :(得分:0)

我没想弄如何用hibernate做这件事。我目前的解决方案只是我在每次启动时执行的普通旧JDBC / SQL逻辑。到目前为止,我对此感到非常高兴。

Connection connection = DriverManager.getConnection(dbUrl, dbUser, dbPassword);

String catalog = connection.getCatalog();
String schema = "public";

DatabaseMetaData databaseMetaData = connection.getMetaData();

ResultSet tablesResultSet = databaseMetaData.getTables(catalog, schema, null, new String[] { "TABLE" });

while(tablesResultSet.next())
{
  String tableName = tablesResultSet.getString("TABLE_NAME");

  LOGGER.info("updating table: '" + tableName + "', setting global sequence");

  // update primary keys to global sequence
  {
    //        LOGGER.info("setting global sequence for '" + tableName + "'.id");

    connection.createStatement().execute("ALTER TABLE \"" + tableName + "\" ALTER COLUMN id TYPE bigint;");
    connection.createStatement().execute("ALTER TABLE \"" + tableName + "\" ALTER COLUMN id SET NOT NULL;");
    connection.createStatement().execute("ALTER TABLE \"" + tableName + "\" ALTER COLUMN id SET DEFAULT nextval('my_global_sequence'::regclass)");
  }
}

答案 1 :(得分:-1)

您可以在id上使用注释来确定您想要使用的序列生成器:

以您的代码为例:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@SequenceGenerator(name="my_global_sequence")
private long id = 0;

使用此注释,可以为每个实体或实体组配置特定的序列生成器,甚至可以在任何地方使用相同的序列生成器。

需要注意的是,您必须为您拥有的每个实体定义该注释