使用 org.hibernate.id.enhanced.SequenceStyleGenerator 实现。
SequenceStyleGenerator is capable of working against databases that do not support sequences by switching to a table as the underlying backing.
The preferred (and portable) way to configure this generator is using the JPA-defined javax.persistence.SequenceGenerator annotation.
Unnamed sequence
package org.example.demo.hibernate;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Persistence;
public class Test {
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();
        Person p = new Person();
        em.getTransaction().begin();
        em.persist(p);
        em.getTransaction().commit();
        em.close();
        factory.close();
    }
    @Entity(name = "Person")
    public static class Person {
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private Long id;
    }
}
生成 SQL
drop table if exists Person cascade
drop sequence if exists hibernate_sequence
create sequence hibernate_sequence start 1 increment 1
create table Person (id int8 not null, primary key (id))
select nextval ('hibernate_sequence')
insert into Person (id) values (1)
Configured sequence
package org.example.demo.hibernate;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Persistence;
import javax.persistence.SequenceGenerator;
public class Test {
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();
        Person p1 = new Person();
        Person p2 = new Person();
        Person p3 = new Person();
        em.getTransaction().begin();
        em.persist(p1);
        em.persist(p2);
        em.persist(p3);
        em.getTransaction().commit();
        em.close();
        factory.close();
    }
    @Entity(name = "Person")
    public static class Person {
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq")
        @SequenceGenerator(name = "my_seq", sequenceName = "my_sequence")
        private Long id;
    }
}
生成 SQL
drop table if exists Person cascade
drop sequence if exists my_sequence
create sequence my_sequence start 1 increment 50
create table Person (id int8 not null, primary key (id))
select nextval ('my_sequence')
select nextval ('my_sequence')
insert into Person (id) values (1)
insert into Person (id) values (2)
insert into Person (id) values (3)
注意
- 只有两次 
select nextval ('my_sequence') - SequenceGenerator 默认的 allocationSize 是 50 表示 pool 大小是 50 。但实际写入 Person 表中的 id 只是加一。
 - 这个序列依次查询 nextval 得到的值应该是 1,51 。数据库中查看 my_sequence 的当前值是 51
 
参见 Optimizers
同一个 sequence 如果要在不同 Entity 中使用,需要在每个 Entity 中都定义一次!
package org.example.demo.hibernate;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Persistence;
import javax.persistence.SequenceGenerator;
public class Test {
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();
        Person p = new Person();
        Address a = new Address();
        em.getTransaction().begin();
        em.persist(p);
        em.persist(a);
        em.getTransaction().commit();
        em.close();
        factory.close();
    }
    @Entity(name = "Person")
    @SequenceGenerator(name = "my_seq", sequenceName = "my_sequence")
    public static class Person {
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq")
        private Long id;
    }
    @Entity(name = "Address")
    @SequenceGenerator(name = "my_seq", sequenceName = "my_sequence")
    public static class Address {
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq")
        private Long id;
    }
}
生成 SQL
drop table if exists Address cascade
drop table if exists Person cascade
drop sequence if exists my_sequence
create sequence my_sequence start 1 increment 50
create table Address (id int8 not null, primary key (id))
create table Person (id int8 not null, primary key (id))
select nextval ('my_sequence')
select nextval ('my_sequence')
select nextval ('my_sequence')
insert into Person (id) values (1)
insert into Address (id) values (52)
注意
- 有三次 
select nextval ('my_sequence') - 实际写入 Address 表中的 id 是 52 。这应该跟多 Tenant 有关
 - 这个序列依次查询 nextval 得到的值应该是 1,51,101 。数据库中查看 my_sequence 的当前值是 101
 
参见 Optimizers
如果 Address 上不加 @SequenceGenerator 则抛异常 org.hibernate.AnnotationException: Unknown Id.generator: my_seq