Come scegliere la strategia di generazione dell'ID quando si utilizza JPA e Hibernate


102

Stavo esaminando la sezione di generazione dell'ID della guida di riferimento di Hibernate e "persistenza java con Hibernate"

Ci sono alcune opzioni disponibili con Hibernate e JPA combinati.

Stavo cercando un'ulteriore documentazione su come scegliere la specifica strategia di generazione dell'ID.

Sto anche cercando punti di svolta.

Ad esempio, la strategia hilo dovrebbe ridurre la contesa. Suppongo che ci debba essere un compromesso associato a questa scelta.

Voglio essere istruito sui compromessi.

C'è della letteratura disponibile?

Risposte:


92

Gli API Doc sono molto chiari su questo.

Tutti i generatori implementano l'interfaccia org.hibernate.id.IdentifierGenerator. Questa è un'interfaccia molto semplice. Alcune applicazioni possono scegliere di fornire le proprie implementazioni specializzate, tuttavia, Hibernate fornisce una gamma di implementazioni integrate. I nomi delle scorciatoie per i generatori incorporati sono i seguenti:

incremento

genera identificatori di tipo long, short o int che sono univoci solo quando nessun altro processo sta inserendo dati nella stessa tabella. Non utilizzare in un cluster.

identità

supporta colonne Identity in DB2, MySQL, MS SQL Server, Sybase e HypersonicSQL. L'identificatore restituito è di tipo long, short o int.

sequenza

utilizza una sequenza in DB2, PostgreSQL, Oracle, SAP DB, McKoi o un generatore in Interbase. L'identificatore restituito è di tipo long, short o int

hilo

utilizza un algoritmo hi / lo per generare in modo efficiente identificatori di tipo long, short o int, data una tabella e una colonna (per impostazione predefinita hibernate_unique_key e next_hi rispettivamente) come fonte di valori hi. L'algoritmo hi / lo genera identificatori che sono univoci solo per un particolare database.

seqhilo

utilizza un algoritmo hi / lo per generare in modo efficiente identificatori di tipo long, short o int, data una sequenza di database denominata.

uuid

utilizza un algoritmo UUID a 128 bit per generare identificatori di tipo stringa che sono univoci all'interno di una rete (viene utilizzato l'indirizzo IP). L'UUID è codificato come una stringa di 32 cifre esadecimali di lunghezza.

guid

utilizza una stringa GUID generata dal database su MS SQL Server e MySQL.

nativo

seleziona identità, sequenza o hilo a seconda delle capacità del database sottostante.

assegnato

consente all'applicazione di assegnare un identificatore all'oggetto prima che venga chiamato save (). Questa è la strategia predefinita se non viene specificato alcun elemento.

Selezionare

recupera una chiave primaria, assegnata da un trigger di database, selezionando la riga da una chiave univoca e recuperando il valore della chiave primaria.

straniero

utilizza l'identificatore di un altro oggetto associato. Di solito viene utilizzato insieme a un'associazione di chiave primaria.

sequenza di identità

una strategia di generazione di sequenze specializzata che utilizza una sequenza di database per la generazione del valore effettivo, ma la combina con getGeneratedKeys JDBC3 per restituire il valore dell'identificatore generato come parte dell'esecuzione dell'istruzione di inserimento. Questa strategia è supportata solo sui driver Oracle 10g destinati a JDK 1.4. I commenti su queste istruzioni di inserimento sono disabilitati a causa di un bug nei driver Oracle.

Se stai costruendo una semplice applicazione con pochi utenti simultanei, puoi scegliere increment, identity, hilo ecc. Questi sono semplici da configurare e non hanno bisogno di molto codice all'interno del db.

Dovresti scegliere la sequenza o il guid a seconda del tuo database. Questi sono sicuri e migliori perché la idgenerazione avverrà all'interno del database.

Aggiornamento: Recentemente abbiamo avuto un problema con l'identità in cui il tipo primitivo (int) è stato risolto utilizzando invece il tipo warapper (Integer).


Molte grazie per la tua risposta. Ho già esaminato i documenti. Tuttavia, sto cercando il motivo per cui le persone dovrebbero usare qualcosa come hilo e seqhilo. Quando facciamo quella scelta. Quali sono i casi d'uso di select.

Quando c'è qualcosa di così semplice come sequenza o guida, cosa può richiedere allo sviluppatore di scegliere altre strade.

1
Ho aggiornato la mia risposta. In realtà incremento, identità, hilo ecc. Sono più semplici. ma non sono adatti per applicazioni aziendali. Mantenere tutte le opzioni non è un problema, ma assicurati di utilizzare quella più adatta a te!
ManuPK

Si. Finora non ho avuto il privilegio di votare o accettare.

Sto cercando di approfondire più dettagli, se hai tempo fammelo sapere.

45

Fondamentalmente, hai due scelte principali:

  • È possibile generare l'identificatore da soli, nel qual caso è possibile utilizzare un identificatore assegnato .
  • Puoi usare l' @GeneratedValueannotazione e Hibernate assegnerà l'identificatore per te.

Per gli identificatori generati hai due opzioni:

Per gli identificatori numerici hai tre opzioni :

  • IDENTITÀ
  • SEQUENZA
  • TAVOLO

IDENTITY è solo una buona scelta quando non è possibile utilizzare SEQUENCE (es. MySQL) perché disabilita gli aggiornamenti batch JDBC .

SEQUENCE è l'opzione preferita, specialmente se usata con un ottimizzatore di identificatori come pooled o pooled-lo .

TABLE deve essere evitato ad ogni costo poiché utilizza una transazione separata per recuperare l'identificatore e i blocchi a livello di riga che scalano male.


20


Tempo fa ho scritto un articolo dettagliato sui generatori di chiavi Hibernate: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

Scegliere il generatore corretto è un compito complicato, ma è importante cercare di farlo bene il prima possibile: una migrazione tardiva potrebbe essere un incubo.

Un po 'fuori tema ma una buona occasione per sollevare un punto solitamente trascurato che è la condivisione delle chiavi tra le applicazioni (tramite API). Personalmente preferisco sempre le chiavi surrogate e se ho bisogno di comunicare i miei oggetti con altri sistemi non espongo la mia chiave (anche se è una chiave surrogata) - utilizzo una 'chiave esterna' aggiuntiva. Come consulente ho visto più di una volta integrazioni di sistema "fantastiche" utilizzando chiavi oggetto (l'approccio "è lì, usiamolo") solo per scoprire un anno o due dopo che una parte ha problemi con l'intervallo di chiavi o qualcosa di simile il tipo che richiede una migrazione profonda sul sistema esponendone le chiavi interne. Esporre la tua chiave significa esporre un aspetto fondamentale del tuo codice a vincoli esterni a cui non dovresti essere esposto.


2

Trovo questa conferenza molto preziosa https://vimeo.com/190275665 , al punto 3 riassume questi generatori e fornisce anche alcune analisi delle prestazioni e una linea guida quando si utilizzano ciascuno di essi.


6
Quel video sembra molto familiare.
Vlad Mihalcea
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.