我刚刚注意到,对于我的实体的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
答案 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会以同样的方式行事。但我可能错了,这似乎并没有规定。