【发布时间】:2012-09-26 13:55:38
【问题描述】:
我们都知道 Hibernate 在使用 @SequenceGenerator 时的默认行为——它将真实数据库序列增加 一个,将此值乘以 50(默认 allocationSize 值)——然后使用此值作为实体 ID。
这是不正确的行为,并与 specification 冲突,它说:
allocationSize - (可选)从序列中分配序列号时增加的数量。
明确一点:我不关心生成的 ID 之间的差距。
我关心与底层数据库序列不一致的 ID。例如:任何其他应用程序(例如使用普通 JDBC)可能想要在从序列获得的 ID 下插入新行 - 但所有这些值可能已经被 Hibernate 使用!疯狂。
有人知道这个问题的任何解决方案吗(不设置allocationSize=1 从而降低性能)?
编辑:
把事情说清楚。
如果最后插入的记录的 ID = 1,则 HB 同时为其新实体使用值 51, 52, 53...:数据库中的序列值将设置为 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>
【问题讨论】:
-
"没有设置 allocationSize=1 从而降低性能"为什么它会降低性能是你设置为 1 吗?
-
@sheidaei 请参阅下面的评论 :-) 这是因为每个
save都需要查询数据库以获取序列的下一个值。 -
谢谢你遇到了同样的问题。起初,我在每个 @SequenceGenerator 中添加了 allocationSize = 1。使用 hibernate.id.new_generator_mappings=true 可以防止这种情况。虽然 JPA 仍然查询数据库以获取每个插入的 id ...
-
使用
SequenceGenerator,只有当allocationsize指定的ID 数量用完时,Hibernate 才会查询数据库。如果您设置了allocationSize = 1,那么这就是 Hibernate 为每个插入查询数据库的原因。改变这个值,你就完成了。 -
谢谢!
hibernate.id.new_generator_mappings设置非常重要。我希望这是默认设置,我不必花太多时间研究为什么 id 号码会变得疯狂。