【问题标题】:Hibernate 5 Sequence Generate IssueHibernate 5 序列生成问题
【发布时间】:2016-03-06 19:45:41
【问题描述】:

我正在从 3 迁移到 hibernate 5。我看到序列生成器在 Hibernate 5 中无法正常工作。我的序列定义为最小值 1000 并递增 1。但是当我尝试创建新的实体记录时,我看到插入了一条 id 为 951 的记录。似乎 id 与实际序列下一个值相比减去了 50。在我的情况下,ID 应该是 1000。

请告诉我任何帮助。

这是我的实体和序列:

实体:

@Entity
@Table(name = "SOME TABLE")
public class Group {

  @Id
  @Column(name = "id")
  @SequenceGenerator(name = "name",  sequenceName ="SEQ_name" )
  @GeneratedValue(strategy = GenerationType.AUTO, generator="name")
  private Long id;

  @Pattern(regexp = "^[^\\*]*$", message = "{3011}")
  @Size(message = "{3014}")
  @NotBlank(message = "{3000}")
  @Column(name = NAME, unique = true, nullable = false)
  private String name;

顺序:

CREATE SEQUENCE  SEQ_name MINVALUE 1000 NOMAXVALUE INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE;

【问题讨论】:

    标签: oracle jpa hibernate-5.x


    【解决方案1】:

    Hibernate 调用 SEQ_name.nextval,但如果 allocationSize 大于 1,它会按 allocationSize 递减并递增 1。

    下一个 (allocationSize-1) 密钥生成是在不与数据库通信的情况下完成的,只需增加 1。

    因此,如果你使用默认的allocationSize 50,会有两个后果:

    序列必须将INCREMENT BY 设置为与allocationSize 相同的值

    要将序列与数据库中的现有键对齐,请将START WITH 设置为

    max(ID) + allocationSize

    这里是一个小例子

    -- START WITH = max(ID) + allocation size 
    -- INCREMENT BY = allocation size
    -- e.g. if 100 is the last key,
    -- to start with a key 101 - set START WITH to 150
    CREATE SEQUENCE hib_seq START WITH 150 INCREMENT BY 50;
    
    
    
    select hib_seq.nextval - 50 + 1 from dual;
    101
    -- 49 times Hibernate performs increase by 1 - keys 102 to 150
    -- new sequence generation
    select hib_seq.nextval - 50 + 1 from dual;
    151
    

    注意此行为要求属性 hibernate.id.new_generator_mappings 为 true 为 recomended

    【讨论】:

    • 我不认为序列缓存有问题,因为在我的情况下,数据库级别的缓存仅为 20 但我得到的是 951 而不是 1000。如果是 20 不同,我怀疑问题出在缓存。但这里的差异是 50,这是默认的 allocationSize
    • @Sydubabu 我知道了 - this 对你来说可能很有趣......
    【解决方案2】:

    您定义的序列不是以 1000 开头,而是以 1(最小值 1)开头。我也看不到您将提到的序列设置为实体使用的序列的位置。

    【讨论】:

    • 这是一个发布错误。更新为实际
    • @Steve Ebersole 任何帮助。
    【解决方案3】:

    在某些情况下,您的 Oracle 用户将能够从另一个 SEQUENCE 可能不正确的用户中选择一个 SEQUENCE。因此,您应该与您的 Oracle 用户核实:

    select * from all_sequences t where t.SEQUENCE_NAME = 'HIB_SEQ';
    

    【讨论】:

    猜你喜欢
    • 2021-10-20
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 2013-02-26
    • 1970-01-01
    • 2019-11-23
    • 2011-11-21
    相关资源
    最近更新 更多