Pergunta

Acabei de notar que para o id da minha entidade, o eclipselink atribui um id 1 + o anteriormente atribuído NA MESMA SESSÃO (1), ao contrário da tabela de elementos (2).Isso vai contra as expectativas da minha aplicação.

Qual é a maneira mais fácil de dizer para fazer 2?

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

E aqui está o que tenho no banco de dados:

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                                                                                      
Foi útil?

Solução

Ao usar um GenerationType.AUTO estratégia com Derby, o EclipseLink assume como padrão um gerador de tabela estratégia.

Então, ao gerar um Id for necessário, EL irá pré-alocar ids de acordo com o allocationSize (que é 50 por padrão).Para isso, primeiro atualizará a coluna que armazena o último valor gerado para incrementá-la pelo allocationSize:

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

E então lerá o novo valor:

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

Uma vez feito isso, EL pré-aloca um conjunto de ids usando o atual valor - alocaçãoSize + 1 como "primeiro" e valor como "último":

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

E servirá ids da memória até atingir o último valor e reiniciará um ciclo.

Agora, se você reiniciar a JVM, não há outra maneira segura para EL do que pré-alocar um novo conjunto de ids, "perdendo" aqueles do intervalo "anterior" que não foram usados ​​(pense em multi-JVMs, etc.), que explica o "salto" de 2 para 51 no seu exemplo.

Se você quiser evitar isso, minha sugestão seria mudar para um IDENTITY estratégia que é suportada pelo Derby (não acho que configurar o gerador de tabela para usar um allocationSize de 1 seria uma boa ideia).


Não acho que configurar o gerador de tabela para usar um alocaçãoSize de 1 seja uma boa ideia.Por que não?

Por causa do impacto no desempenho, se você precisar ler a tabela de "sequência" para cada inserção.Mas por outro lado, 1) isso pode não ser uma preocupação no seu caso 2) Essa é a única estratégia que permite obter ids verdadeiramente sequenciais.

Se estiver interessado, você poderá configurar isso globalmente usando o table-generator elemento no descritor XML.

EL desencoraja fortemente a estratégia de identidade, além de parecer que existem minas (porque você deve esperar para confirmar antes de ler o valor, algo que posso estar fazendo em algum lugar).

Bem, não posso confirmar para EL (não vou testar isso agora), mas o Hibernate realiza uma inserção imediata em persist quando você usa um IDENTITY estratégia.Achei que EL se comportaria da mesma maneira.Mas posso estar errado, isso não parece obrigatório pelas especificações.

Referências

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top