一尘不染

Hibernate,@ SequenceGenerator和allocationSize

hibernate

我们都知道使用Hibernate时的默认行为@SequenceGenerator-它使实际数据库序列增加
,将该值乘以50(默认allocationSize值)-然后将该值用作实体ID。

这是错误的行为,并与说明以下内容的规范冲突:

distributionSize-(可选)从序列中分配序列号时要增加的数量。

需要明确的是:我不关心生成的ID之间的差距。

我关心与基础数据库序列 不一致的 ID 。例如:任何其他应用程序(例如,使用纯JDBC)可能要在从序列获得的ID下插入新行-
但所有这些值可能已被Hibernate使用!疯狂。

有人知道任何解决此问题的方法(没有设置allocationSize=1,从而降低性能)吗?

编辑:
弄清楚。如果最后插入的记录的ID = 1,则HB同时51, 52, 53...在其新实体BUT中使用值:数据库中序列的值将设置为2。当其他应用程序使用该序列时,很容易导致错误。

另一方面:规范(据我所知)说数据库序列应该设置为51,同时HB应该使用范围内的值 2, 3 ... 50

更新:
正如下面的史蒂夫·埃伯索尔(Steve
Ebersole)所述:通过设置可以启用我描述的行为(也是许多人中最直观的行为)hibernate.id.new_generator_mappings=true

谢谢大家。

更新2:
对于将来的读者,您可以在下面找到一个有效的示例。

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
    @SequenceGenerator(name = "USERS_SEQ", sequenceName = "SEQUENCE_USERS")
    private Long id;
}

persistence.xml

<persistence-unit name="testPU">
  <properties>
    <property name="hibernate.id.new_generator_mappings" value="true" />
  </properties>
</persistence-unit>

阅读 648

收藏
2020-06-20

共1个答案

一尘不染

绝对清楚…您所描述的内容与规范没有 任何 冲突。该规范讨论的是Hibernate分配给您的实体的值,而不是实际存储在数据库序列中的值。

However, there is the option to get the behavior you are looking for. First
see my reply on Is there a way to dynamically choose a @GeneratedValue
strategy using JPA annotations and
Hibernate?
That will give
you the basics. As long as you are set up to use that SequenceStyleGenerator,
Hibernate will interpret allocationSize using the “pooled optimizer” in the
SequenceStyleGenerator. The “pooled optimizer” is for use with databases that
allow an “increment” option on the creation of sequences (not all databases
that support sequences support an increment). Anyway, read up about the
various optimizer strategies there.

2020-06-20