17

我有一个无法解决的问题。在休眠状态下,我对以下内容没有任何问题:

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

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

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500;

这里没什么可看的。一切都按预期工作。但是,如果我将提供程序切换到 EclipseLink,我会收到此错误:

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

所以我当然会四处搜索,如果初始值为 1 并且它应该等于 allocationSize,那么我会看到一些关于 EclipseLink 创建负数的信息。

所以,好吧,所以添加“initialValue=500”并将我的 DDL 脚本更新为“START 500”可以解决这个问题,但现在我的编号从 500 而不是 1 开始。什么给出了?这是一个 EclipseLink 错误还是我不理解的东西。我想生成从 1 开始并且分配大小调整到实体(在本例中为 500)的序列。我将如何使用 EclipseLink 做到这一点?

谢谢!

另一种问这个问题的方法是……鉴于这个 DDL:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500;

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

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

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

会生成这个:

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500;

这意味着不可能使用 EclipseLink 创建具有“START WITH 1”的 DDL。

4

3 回答 3

25

默认情况下,@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;
}

EclipseLink 似乎使用以下公式计算了“顺序”实体 ID:

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 (default)

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500;

生产

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;

生产

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;

生产

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

为了满足您的要求,应使用以下一种:

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

生产

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

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

DROP SEQUENCE email_seq_gen RESTRICT;

我希望它有所帮助。

于 2013-11-28T13:23:55.853 回答
2

你的序列应该从 500 而不是 1 开始。如果你从 1 开始,那么第一个 nextval 只会给你 1 个 id 而不是 500。

否则在设置完序列后调用 nextval ,所以它到达 501。

错误是警告还是错误?如果你只是忽略它,它仍然有效吗?

于 2013-08-28T15:11:20.947 回答
1

我可以通过在模式生成中添加一句话来解决这个问题:RESTART

实体定义

@GeneratedValue(strategy=GenerationType.SEQUENCE, generator=Secuences.PROFILES_SEQ)
@SequenceGenerator(name=Secuences.PROFILES_SEQ, sequenceName=Secuences.PROFILES_SEQ, allocationSize=25)
@Column( name = "id" )
private Long internalId;

SQL 模式初始化

-- create sequence
CREATE SEQUENCE PROFILES_SEQ START WITH 1;

-- use sequence to set values in column
UPDATE public.cc_user_profile SET id = nextval('PROFILES_SEQ');

-- update sequence
ALTER SEQUENCE PROFILES_SEQ INCREMENT BY 25 START WITH 25;
ALTER SEQUENCE PROFILES_SEQ RESTART;

希望它可以帮助某人。

于 2018-08-10T20:24:14.783 回答