我在Spring和DB2中使用Hibernate。我正在使用序列为实体生成主键。所有实体都使用相同的序列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.执行此操作的正确方法是什么?
答案 0 :(得分:2)
Hibernate似乎做了以下事情:
当hibernate需要主键时,它将从序列中获取值。 Hibernate将从单个序列值生成多个主键值。例如,hibernate将保留一个内部计数器,其值附加到序列值以获取主键值。当内部计数器达到其限制时,计数器复位,获得序列中的新值,并且主键过程重新开始。
例如:
这会产生以下影响:
要使hibernate使用从序列中获取的实际值,可以使用此映射:
@Id
@GeneratedValue(generator="hibernate_sequence")
@GenericGenerator(strategy="sequence", name="hibernate_sequence")
private Integer id;
答案 1 :(得分:0)
DB2 create sequence命令上有一些可能会影响它的选项。 INCREMENT_BY表示每次调用nextval会增加多少值。带有NO_ORDER的CACHE保留一定数量的值,因此如果多个连接使用相同的序列,则可以更快地获取值,但代价是无序值。在深入研究Hibernate之前,我会检查序列是如何创建的。通过查看Hibernate代码,它非常简单 - 查看DB2Dialect,您可以看到它用于获取序列值的sql。
答案 2 :(得分:0)
我在allocationSize
注释中解决了将@SequenceGenerator
设置为1的问题。
示例:
@MappedSuperclass
public class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GENERATOR")
private Integer id;
和实体:
@SequenceGenerator(name = "SEQ_GENERATOR", sequenceName = "MY_SEQUENCE", allocationSize = 1)
public class MyEntity extends AbstractEntity {