Domanda

Ho appena notato che per l'ID della mia entità, Eclipselink assegna un ID 1 + il precedentemente grande assegnato nella stessa sessione (1), al contrario della tabella degli elementi (2). Questo va contro le mie aspettative di applicazione.

Qual è il modo più semplice per dirlo a fare 2?

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

Ed ecco cosa ho nel database:

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                                                                                      
È stato utile?

Soluzione

Quando si usa un GenerationType.AUTO Strategia con Derby, Eclipselink è inadempiente a a Generatore di tabelle strategia.

Quindi, quando si genera un Id è richiesto, EL preallocherà IDS secondo il allocationSize (che è 50 per impostazione predefinita). Per fare ciò, aggiornerà prima la colonna che memorizza l'ultimo valore generato per incrementarla dal allocationSize:

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

E quindi leggerà il nuovo valore:

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

Una volta fatto, EL prealloca un pool di ID usando la corrente valore - Allocationsze + 1 come "primo" e valore come "ultimo":

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

E servirà gli ID dalla memoria fino a raggiungere l'ultimo valore e riavvierà un ciclo.

Ora, se riavvia il JVM, non esiste un altro modo sicuro per EL che preallocare un nuovo pool di ID, "perdere" quelli della gamma "precedente" che non sono stati utilizzati (pensa a multi-jvms ecc.), Che Spiega il "salto" da 2 a 51 nel tuo esempio.

Se vuoi evitarlo, il mio suggerimento sarebbe quello di passare a un IDENTITY Strategia supportata da Derby (non credo che configurare il generatore di tabelle per usare un allocationSize di 1 sarebbe una buona idea).


Non credo che configurare il generatore di tabelle per utilizzare un allocations di 1 sarebbe una buona idea. Perché no?

A causa del colpo delle prestazioni se devi leggere dalla tabella "sequenza" per ogni inserto. D'altra parte, 1) questa potrebbe non essere una preoccupazione nel tuo caso 2) Questa è l'unica strategia che consente di ottenere ID veramente sequenziali.

Se sei interessato, dovresti essere in grado di configurarlo a livello globale utilizzando il table-generator Elemento nel descrittore XML.

El scoraggia altamente la strategia di identità, inoltre sembra che ci siano miniere (perché devi aspettare di impegnarti prima di leggere il valore, qualcosa che potrei fare da qualche parte).

Bene, non posso confermare per El (non lo tenerò in questo momento) ma Hibernate esegue un inserto immediato su persist Quando usi un IDENTITY strategia. Pensavo che El si sarebbe comportato allo stesso modo. Ma potrei sbagliarmi, questo non sembra obbligatorio dalle specifiche.

Riferimenti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top