【问题标题】:How to enable the Hibernate HiLo entity identifier optimizer strategy如何启用 Hibernate HiLo 实体标识符优化器策略
【发布时间】:2015-12-31 20:53:25
【问题描述】:

我正在通过类似

的方式在没有任何 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,但它似乎完全被忽略了

【问题讨论】:

  • 默认值总是没用,为什么不使用物理序列,如果在每行之前插入触发器,也可以使用自动增量。

标签: java hibernate entity identifier hilo


【解决方案1】:

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

下面的示例 sn-p 使用 @GenericGenerator 注释和 hilo 优化器和 SEQUENCE 策略设置 increment_size

@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 配置属性。

【讨论】:

    【解决方案2】:

    @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 的问题是生成的标识符不包含数据库序列值,因此使用数据库的第 3 方客户端将不知道如何生成下一个标识符值,除非他们知道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 的工作原理,请查看此图:

    如果您一直在使用旧版 hilo 优化器,您可能希望切换到使用 pooledpooled-lo,因为 hilo 无法与可能不知道 hilo 的其他客户端互操作标识符分配策略。

    【讨论】:

    猜你喜欢
    • 2014-05-28
    • 1970-01-01
    • 2013-07-20
    • 2010-10-05
    • 1970-01-01
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多