EclipseLink和序列生成器预分配

rob*_*lco 15 hibernate jpa eclipselink

我有一个问题我无法理解.在休眠中,我对以下内容没有任何问题:

@GeneratedValue( strategy = GenerationType.AUTO, generator = "email-seq-gen" )
@SequenceGenerator( name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", allocationSize=500 )
Run Code Online (Sandbox Code Playgroud)

然后在我的schema.ddl中我有这个:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500;
Run Code Online (Sandbox Code Playgroud)

在这里看不多.一切都按预期工作.但是,如果我将提供程序切换到EclipseLink,我会收到此错误:

The sequence named [EMAIL_SEQ_GEN] is setup incorrectly.  Its increment does not match its pre-allocation size.
Run Code Online (Sandbox Code Playgroud)

所以当然我谷歌周围看到一些关于EclipseLink创建负数的事情,如果初始值是1并且它应该等于allocationSize.

所以,好吧,所以添加"initialValue = 500"并将我的DDL脚本更新为"START 500"修复了这个问题,但现在我的编号从500开始而不是1.什么给出了?这是一个EclipseLink错误还是我不理解的东西.我想生成从1开始并具有调整到实体的分配大小的序列(在本例中为500).我如何使用EclipseLink执行此操作?

谢谢!

另一种问这个问题的方法是......给出这个DDL:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500;
Run Code Online (Sandbox Code Playgroud)

注释我的实体与EclipseLink一起使用它的正确方法是什么?

如果我让EclipseLink生成我的DDL,那么:

@GeneratedValue( strategy = GenerationType.AUTO, generator = "email-seq-gen" )
@SequenceGenerator( name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", initialValue=1, allocationSize=500 )
Run Code Online (Sandbox Code Playgroud)

会产生这个:

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500;
Run Code Online (Sandbox Code Playgroud)

哪种意味着使用EclipseLink创建一个"START WITH 1"的DDL是不可能的.

wyp*_*prz 20

默认情况下,实体@SequenceGenerator使用initialValue = 1和alocationSize = 50进行注释.

public @interface SequenceGenerator {
    /** 
     * (Optional) The value from which the sequence object 
     * is to start generating.
     */
    int initialValue() default 1;

    /**
     * (Optional) The amount to increment by when allocating 
     * sequence numbers from the sequence.
     */
    int allocationSize() default 50;
}
Run Code Online (Sandbox Code Playgroud)

"顺序"实体id似乎由EclipseLink使用以下公式计算:

entityId = initialValue - allocationSize + INCREMENT_BY
Run Code Online (Sandbox Code Playgroud)

或者在使用DDL的情况下:

entityId = START_WITH - allocationSize + INCREMENT_BY
Run Code Online (Sandbox Code Playgroud)

回到你的特定情况:


@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500
) // initialValue=1 (default)

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500;
Run Code Online (Sandbox Code Playgroud)

产生

entityId = 1 - 500 + 1 = -500 // EclipseLink error
Run Code Online (Sandbox Code Playgroud)
@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=1, 
    allocationSize=500 )

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500;
Run Code Online (Sandbox Code Playgroud)

产生

entityId = 1 - 500 + 1 = -500 // EclipseLink error
Run Code Online (Sandbox Code Playgroud)
@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=500, 
    allocationSize=500
)

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 500;
Run Code Online (Sandbox Code Playgroud)

产生

entityId = 500 - 500 + 500 = 500 // fine, but inappropriate
entityId = 500 - 500 + 1000 = 1000 // incremented by 500
entityId = 500 - 500 + 1500 = 1500 // incremented by 500
...
Run Code Online (Sandbox Code Playgroud)

为满足您的要求,应使用以下方法:

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) but 'START WITH'=500

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 1;
Run Code Online (Sandbox Code Playgroud)

产生

entityId = 500 - 500 + 1 = 1
entityId = 500 - 500 + 2 = 2
entityId = 500 - 500 + 3 = 3
...
Run Code Online (Sandbox Code Playgroud)

可以使用以下SQL 命令从基础数据库中删除现有序列:

DROP SEQUENCE email_seq_gen RESTRICT;
Run Code Online (Sandbox Code Playgroud)

我希望它有所帮助.

  • 创建增量为 1 的序列是错误的。EclipseLink 对每个分配批次仅调用一次序列(在这种情况下,对于在同一事务中添加的每 500 个实体一次)。因此增量必须等于 500。是的,当分配批次小于 500 时,数字将被跳过,但由于对序列的调用较少,这是您为提高效率而付出的代价。要查看发生的错误,请添加两个实体,然后终止 Java 程序,然后添加另一个实体。由于 ID 重复,将发生 java.sql.SQLIntegrityConstraintViolationException。 (2认同)