Hibernate 和 DB2 序列的奇怪行为
我将 Hibernate 与 Spring 和 DB2 一起使用。我正在使用序列来生成实体的主键。所有实体都使用相同的序列 HIBERNATE_SEQUENCE
,这是 hibernate 默认值。
问题在于,最终进入主键的值大约比 HIBERNATE_SEQUENCE 返回的值高 10 倍。
例如,在将新行插入到 tbl 后出现这种情况:
select max(id) as primary_key, nextval for hibernate_sequence sequence_value from tbl ;
primary_key sequence_value
501483661 50148373
我已经在所有实体的超类中像这样映射了主键:
@MappedSuperclass
public class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Integer id;
我希望 hibernate 使用从序列中获取的那些值,而不是序列值乘以 10这样做的正确方法是什么?
I am using Hibernate with Spring and DB2. I am using sequences to generate primary key for entities. All entities use the same sequence HIBERNATE_SEQUENCE
, which is the hibernate default.
The problem is that values that end up into primary keys are about 10 times higher than those returned by the HIBERNATE_SEQUENCE.
For example this situation just after a new row is inserted to tbl:
select max(id) as primary_key, nextval for hibernate_sequence sequence_value from tbl ;
primary_key sequence_value
501483661 50148373
I have mapped primary key like this, in super class for all entities:
@MappedSuperclass
public class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Integer id;
I'd like that hibernate uses those values it fetches from the sequence, not sequence values multiplied by 10. What is the correct way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Hibernate 似乎执行以下操作:
当 hibernate 需要主键时,它将从序列中获取值。 Hibernate 将从单个序列值生成多个主键值。例如,hibernate将保留一个内部计数器,其值附加到序列值以获取主键值。当内部计数器达到其极限时,计数器将重置,从序列中获取新值,并且主键过程重新开始。
例如:
这会导致以下效果:
要使 Hibernate 使用从序列获得的实际值,可以使用以下映射:
Hibernate seems to do following:
When hibernate needs a primary key it will fetch the value from sequence. Hibernate will generate several primary key values from single sequence values. For example hibernate will keep a internal counter whose value is appended to sequence value to obtain the primary key value. When the internal counter hits its limit the counter is reset, a new value from sequence is obtained and primary key process starts all over again.
For example:
This causes following effects:
To make hibernate use actual values obtained from sequence, this mapping can be used:
我解决了这个问题,在@SequenceGenerator注释中将allocationSize设置为1。
示例:
和实体:
I solved this problem setting
allocationSize
to 1 in@SequenceGenerator
annotation.Example:
and the entity:
DB2 createequence 命令上有一些选项可能会影响这一点。 INCRMENT_BY 表示每次调用 nextval 时要增加多少值。使用 NO_ORDER 的 CACHE 保留一定数量的值,因此如果多个连接使用相同的序列,它们可以更快地获取值,但代价是值乱序。在深入研究 Hibernate 之前,我会首先检查序列是如何创建的。从查看 Hibernate 代码来看,它非常简单 - 查看 DB2Dialect,您可以看到它用于获取序列值的 sql。
There are a few options on the DB2 create sequence command that might affect this. INCREMENT_BY says how much to increase the value with each call to nextval. CACHE with NO_ORDER reserves a certain number of values so if multiple connections are using the same sequence they can get values faster at the cost of the values being out of order. I would check to see how the sequence was created first before digging into Hibernate. From looking at the Hibernate code, it's pretty straightforward - look at DB2Dialect and you can see the sql it uses to get the sequence value.