为什么eclipselink每次重启时都会消耗整个allocationSize?

时间:2010-10-27 20:57:16

标签: java orm jpa eclipselink jpa-2.0

我刚刚注意到,对于我的实体的id,eclipselink分配一个id 1 +先前在同一会话中分配的greated(1),而不是在元素表(2)中。这违背了我的应用期望。

告诉它做2的最简单方法是什么?

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int objId;

以下是我在数据库中的内容:

ij> connect 'jdbc:derby:db';
ij> set schema memo;
0 Zeilen eingef?gt/aktualisiert/gel?scht
ij> select * from meaning;
OBJID      |LASTPUBLI&|USR_EMAIL                                                                                                                       
-------------------------------------------------------------------------------------------------------------------------------------------------------
1          |NULL      |NULL                                                                                                                            
2          |2010-10-27|NULL                                                                                                                            
51         |NULL      |NULL                                                                                                                            
101        |NULL      |NULL                                                                                      

1 个答案:

答案 0 :(得分:3)

在Derby中使用GenerationType.AUTO策略时,EclipseLink默认使用表生成器策略。

然后,当需要生成Id时,EL将根据allocationSize(默认为50)预分配id。为此,它将首先更新存储生成的最后一个值的列,以便allocationSize增加它:

UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
    bind => [50, SEQ_GEN]

然后会读取新值:

SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
    bind => [SEQ_GEN]

完成后,EL会使用当前 - allocateSize + 1作为“first”和 value 作为“last”预先分配id池:

local sequencing preallocation for SEQ_GEN: objects: 50 , first: 1, last: 50

并且将从内存中提供ID,直到达到最后一个值并重启一个循环。

现在,如果重新启动JVM,那么EL没有其他安全方法可以预先分配新的id池,“丢失”那些尚未使用的“之前”范围(想想多JVM等等) ),它解释了你的例子中从2到51的“跳跃”。

如果你想避免这种情况,我的建议是切换到Derby支持的IDENTITY策略(我不认为配置表生成器使用allocationSize为1会是一个好主意。)


  

我认为配置表生成器以使用allocationSize不是一个好主意。为什么不?

如果必须从每个插入的“序列”表中读取,性能会受到影响。但另一方面,1)在您的情况下这可能不是一个问题2)这是唯一允许获得真正顺序ID的策略。

如果您感兴趣,您应该能够使用XML描述符中的table-generator元素全局配置它。

  EL高度不鼓励身份策略,除了它似乎有地雷(因为你必须等到提交之前读取值,我可能在某处做某事)。

好吧,我无法确认EL(我现在不会对此进行测试)但是当您使用persist策略时,Hibernate会在IDENTITY上执行立即插入。我以为EL会以同样的方式行事。但我可能错了,这似乎并没有规定。

参考