使用 PostgreSQL 的一个实体的多个 Hibernate 序列生成器

Multiple Hibernate sequence generators for one entity with PostgreSQL

我可以为一个实体使用多个序列生成器吗,比如

@Id
@SequenceGenerator(name=”subscription_id_seq”,sequenceName=”subscription_id_seq”, allocationSize=7)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator=”subscription_id_seq”)
@Column(unique=true, nullable=false)
private Integer id

@Column(name="code", nullable=false, unique=true )
@SequenceGenerator(name="subscription_code_1_seq",sequenceName="subscription_code_1_seq", allocationSize=7)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="subscription_code_1_seq")
private Integer code;

简而言之,您可以为一个实体使用多个序列生成器,但仅用于主键(复合主键)。

来自 SequenceGenerator 文档:

Defines a primary key generator that may be referenced by name when a generator element is specified for the GeneratedValue annotation. A sequence generator may be specified on the entity class or on the primary key field or property. The scope of the generator name is global to the persistence unit (across all generator types).

代码示例:

public class TestPK implements Serializable {

    private Integer test1;

    private Integer test2;

    ...
}

@Entity
@IdClass(TestPK.class)
public class Test implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "seq_test1", sequenceName = "seq_test1", allocationSize = 7)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_test1")
    @Column(name = "test1", unique = true, nullable = false)
    private Integer test1;

    @Id
    @Column(name = "test2", nullable = false, unique = true)
    @SequenceGenerator(name = "seq_test2", sequenceName = "seq_test2", allocationSize = 7)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_test2")
    private Integer test2;

    ...

    @Override
    public String toString() {
        return "Test{" +
                "test1=" + test1 +
                ", test2=" + test2 +
                '}';
    }
}

public interface TestRepository extends Repository<Test, String> {

    Page<Test> findAll(Pageable pageable);

    void save(Test test);
}

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private TestRepository testRepository;

    @Override
    public void run(String... args) throws Exception {
        testRepository.save(new Test());
        Page<Test> all = testRepository.findAll(null);
        System.out.println(all.iterator().next());
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

不,你不能。生成器仅适用于标识符列。

确保使用脚本创建此序列(例如 hibernate.hbm2ddl.import_files):

create sequence subscription_code_1_seq start 1 increment 7

然后使用这样的映射:

@Id
@SequenceGenerator(
        name="subscription_id_seq",
        sequenceName="subscription_id_seq",
        allocationSize=7
)
@GeneratedValue(
        strategy=GenerationType.SEQUENCE,
        generator="subscription_id_seq"
)
@Column(unique=true, nullable=false)
private Integer id;

@Column(
        name="code",
        nullable=false,
        unique=true,
        insertable = false,
        updatable = false,
        columnDefinition = "BIGINT DEFAULT nextval('subscription_code_1_seq')"
)
@Generated(GenerationTime.INSERT)
private Integer code;