且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

EclipseLink和序列生成器预分配

更新时间:2022-10-15 12:07:23

默认情况下,使用 @SequenceGenerator 注解的实体使用initialValue = 1并且alocationSize = 50。

  public @interface SequenceGenerator {
/ **
*(可选)序列对象
*开始产生的值。
* /
int initialValue()default 1;

/ **
*(可选)从序列中分配
*序号时的增加量。
* /
int allocationSize()默认50;
}

一个顺序实体id似乎是由EclipseLink通过以下公式:

  entityId = initialValue  -  allocationSize + INCREMENT_BY 

或使用DDL时:

  entityId = START_WITH  -  allocationSize + INCREMENT_BY 

回到您的特殊情况:




  @SequenceGenerator(
name =email-seq-gen,
sequenceName =EMAIL_SEQ_GEN,
allocationSize = 500
)// initialValue = 1(默认值)

CREATE SEQUENCE EMAIL_SEQ_GEN以1增加500开始;

产生

  entityId = 1  -  500 + 1 = -500 // EclipseLink错误






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

CREATE SEQUENCE EMAIL_SEQ_GEN以1增加500开始;

产生

  entityId = 1  -  500 + 1 = -500 // EclipseLink错误






  @SequenceGenerator(
name =email-seq-gen,
sequenceName =EMAIL_SEQ_GEN,
initialValue = 500,
allocationSize = 500


CREATE SEQUENCE EMAIL_SEQ_GEN以500增加500开始;

产生

  entityId = 500  -  500 + 500 = 500 //罚款,但不适用
entityId = 500 - 500 + 1000 = 1000 //增加500
entityId = 500 - 500 + 1500 = 1500 //增加500
...






为了满足您的要求,应该使用以下内容:

  @SequenceGenerator(
name =email-seq -gen,
sequenceName =EMAIL_SEQ_GEN,
allocationSize = 500
)// initialValue = 1(默认),但是'START WITH'= 500

CREATE SEQUENCE EMAIL_SEQ_GEN以500增加1开始;

产生

  entityId = 500  -  500 + 1 = 1 
entityId = 500 - 500 + 2 = 2
entityId = 500 - 500 + 3 = 3
...






使用以下SQL可以从底层数据库中删除现有序列命令

  DROP SEQUENCE email_seq_gen RESTRICT; 

我希望它有帮助。


I have an issue I can't get my head around. In hibernate I have no problem with the following:

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

Then in my schema.ddl I have this:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500;

Not much to see here. Everything works as expected. However, if I switch my provider to EclipseLink I get this error:

The sequence named [EMAIL_SEQ_GEN] is setup incorrectly.  Its increment does not match its pre-allocation size.

So of course I google around and see something about EclipseLink creating a negative number if the initial value is 1 and that it should equal the allocationSize.

So, okay, so adding "initialValue=500" and updating my DDL scripts to "START 500" fixes this but now my numbering starts at 500 instead of 1. What gives? Is this an EclipseLink bug or is there something I am not understanding. I would like to generate sequences that start at 1 and have allocation sizes that are tuned to the entity (in this case 500). How would I do that with EclipseLink?

Thanks!

Another way to ask this is....given this DDL:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500;

What is the correct way to annotate my entity to use it with EclipseLink?

If I let EclipseLink generate my DDL then this:

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

Will generate this:

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500;

Which kind of implies that it is IMPOSSIBLE to create a DDL with a "START WITH 1" using EclipseLink.

By default entities annotated with @SequenceGenerator use initialValue=1 and 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;
}

A "sequential" entity id seems to be calculated by EclipseLink with the following formula:

entityId = initialValue - allocationSize + INCREMENT_BY

or in case of using DDL:

entityId = START_WITH - allocationSize + INCREMENT_BY

Going back to your particular cases:


@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;

produces

entityId = 1 - 500 + 1 = -500 // EclipseLink error


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

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500;

produces

entityId = 1 - 500 + 1 = -500 // EclipseLink error


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

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 500;

produces

entityId = 500 - 500 + 500 = 500 // fine, but inappropriate
entityId = 500 - 500 + 1000 = 1000 // incremented by 500
entityId = 500 - 500 + 1500 = 1500 // incremented by 500
...


To meet your requirements the following one should be used:

@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;

produces

entityId = 500 - 500 + 1 = 1
entityId = 500 - 500 + 2 = 2
entityId = 500 - 500 + 3 = 3
...


An existing sequence can be removed from the underlying database with the following SQL command:

DROP SEQUENCE email_seq_gen RESTRICT;

I hope it helps.