我们都知道使用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>
save
需要查询数据库以获取序列的下一个值。
SequenceGenerator
Hibernate仅在由指定的ID数量allocationsize
用完时才查询数据库。如果进行了设置,allocationSize = 1
这就是Hibernate向数据库查询每个插入的原因。更改此值,您就完成了。
hibernate.id.new_generator_mappings
设置是非常重要的。我希望这是默认设置,我不必花费太多时间来研究ID号为何变得疯狂。