如何启用 Hibernate HiLo 实体标识符优化器策略

How to enable the Hibernate HiLo entity identifier optimizer strategy

我在没有任何 XML 的情况下通过

之类的方式初始化 Hibernate
org.hibernate.SessionFactory sessionFactory = 
    new org.hibernate.cfg.Configuration().
    .setProperty(...)
    .setProperty(...)
    ...
    .buildSessionFactory();

我的 类 使用像

这样的 ID
@Id @Generated(GenerationTime.INSERT) @GeneratedValue private Integer id;

使用的生成器是 SequenceStyleGenerator,它似乎是已弃用的 SequenceGeneratorSequenceHiLoGenerator 等的替代品。它使用

public static final int DEFAULT_INCREMENT_SIZE = 1;

并且似乎允许通过

进行配置
public static final String INCREMENT_PARAM = "increment_size";

但这就是我能找到的全部。我想我必须设置一些 属性 "xxx.yyy.increment_size" 或以另一种方式将其传递给 Hibernate,但我看不出如何。


我知道@SequenceGenerator,但似乎完全被忽略了

我猜您正在寻找如何为您的 SequenceSytleGenerator 设置 increment_size 属性。

下面的示例片段设置 increment_size 使用 @GenericGenerator 注释与 hilo 优化器和 SEQUENCE 策略。

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_generator")
@GenericGenerator(
        name = "hilo_generator",
        strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
        parameters = {
                // Or leave it out to get "hibernate_sequence".
                @Parameter(name = "sequence_name", value = "hilo_sequence"),
                // Or leave it out as this is the default.
                @Parameter(name = "initial_value", value = "1"),
                @Parameter(name = "increment_size", value = "5"),
                @Parameter(name = "optimizer", value = "hilo")
        })

无法使用 Hibernate 配置 属性 全局设置 DEFAULT_INCREMENT_SIZE。您需要改用 @Id 配置属性。

@Generated 与@GeneratedValue

您不需要将 @Generated@GeneratedValue 一起使用。 @Generated 注释用于数据库在 INSERT 或 UPDATE 期间生成的非 id 实体属性。有关 @Generated 注释的更多详细信息。

另一方面,@GeneratedValue仅用于实体标识符属性,当持久化实体时自动生成实体标识符时需要使用它。

序列生成器

当您持久化实体时,序列生成器需要额外的数据库往返来调用序列对象。出于这个原因,Hibernate 提供了基于序列的优化器来减少获取实体标识符值所需的往返次数。

现在,如果您想使用 hilo,标识符映射将如下所示:

@Id
@GeneratedValue(
    strategy = GenerationType.SEQUENCE, 
    generator = "post_sequence"
)
@GenericGenerator(
    name = "post_sequence",
    strategy = "sequence",
    parameters = {
        @Parameter(name = "sequence_name",  value = "post_sequence"),
        @Parameter(name = "initial_value",  value = "1"),
        @Parameter(name = "increment_size",  value = "3"),
        @Parameter(name = "optimizer", value = "hilo")
    }
)
private Long id;

除了必须使用特定于 Hibernate 的 @GenericGenerator 之外,hilo 的问题是生成的标识符不包括数据库序列值,因此使用数据库不知道如何生成下一个标识符值,除非他们知道 hilo 算法和 allocationSize.

因此,最好使用pooledpooled-lo

合并优化器

pooled 优化器非常容易设置。您需要做的就是设置 JPA @SequenceGenerator 注释的 allocationSize,Hibernate 将切换到使用 pooled 优化器:

@Id
@GeneratedValue(
    strategy = GenerationType.SEQUENCE,
    generator = "post_sequence"
)
@SequenceGenerator(
    name = "post_sequence",
    sequenceName = "post_sequence",
    allocationSize = 3
)
private Long id;

Pooled-lo 优化器

要使用pooled-lo优化器,只需添加以下配置属性:

<property name="hibernate.id.optimizer.pooled.preferred" value="pooled-lo" />

现在,实体标识符映射与我之前向您展示的 pooled 优化器相同。

要了解 pooled-lo 的工作原理,请查看此图:

If you have been using the legacy hilo optimizer, you might want to switch to using pooled or pooled-lo, as hilo is not interoperable with other clients that might not be aware of the hilo identifier allocation strategy.