Hibernate 不使用 Liquibase 中定义的序列

Posted

技术标签:

【中文标题】Hibernate 不使用 Liquibase 中定义的序列【英文标题】:Hibernate not using sequence defined in Liquibase 【发布时间】:2018-02-08 13:44:04 【问题描述】:

我在liquibase 更改日志中定义了一个序列,但看起来Hibernate 在插入实体时忽略了它。

Liquibase 中定义的序列如下所示。

<createSequence cycle="false" incrementBy="1"
            startValue="1" maxValue="9223372036854775807" minValue="1"
            sequenceName="seq_vehicle" />

在实体类中。

@Entity
@Table(name = "VEHICLE")
public class Vehicle 

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "VEHICLE_SEQ")
    @SequenceGenerator(name = "VEHICLE_SEQ", sequenceName = "SEQ_VEHICLE")
    private Long id;

我也将此属性添加到hibernate.cfg.xml

<property name="hibernate.id.new_generator_mappings">false</property>

问题在于,每当将新实体插入数据库时​​,它都会忽略 Liquibase 序列,并从 50 开始,并为任何新插入增加 50。我该如何解决?

【问题讨论】:

尝试将序列名称小写:sequenceName = "seq_vehicle" on @SequenceGenerator 【参考方案1】:

使用@GenericGenerator 代替@SequenceGenerator

@Id
@Column
@GenericGenerator(
    name = "VEHICLE_SEQ", 
    strategy = "sequence", 
    parameters = 
        @org.hibernate.annotations.Parameter(name = "sequence", value = "SEQ_VEHICLE")
    
)
@GeneratedValue(generator = "VEHICLE_SEQ")
private Long id;

@SequenceGenerator 在您的情况下是休眠的 HILO 机制,默认情况下使用 50 的默认分配大小,这就是为什么您会在数据库中看到 id 值的差距。

【讨论】:

【参考方案2】:

只需添加allocationSize = 1:

@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "VEHICLE_SEQ")
@SequenceGenerator(name = "VEHICLE_SEQ", sequenceName = "SEQ_VEHICLE", allocationSize = 1)
private Long id;

正如@veljkost 解释的那样,allocationSize is 50 的默认值。

【讨论】:

以上是关于Hibernate 不使用 Liquibase 中定义的序列的主要内容,如果未能解决你的问题,请参考以下文章

使用多个数据库和 Liquibase 时的最佳 Hibernate 主键生成类型

在 Gradle Spring Boot Hibernate 项目中设置 LiquiBase

无法让 liquibase-hibernate 插件与 gradle 一起工作

Liquibase:如何使用 CURRENT_TIMESTAMP 加载数据?

如何在 liquibase OracleDatabase 中添加保留关键字?

Liquibase 看不到实体的变化