Domanda

la mia entità chiave primaria appare come di seguito

@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;

quando corro, ricevo un errore

impossibile ottenere o aggiornare il valore successivo; l'eccezione nidificata è org.hibernate.exception.SQLGrammerException: impossibile ottenere o aggiornare il valore successivo

ma quando cambio a

@GeneratedValue 
private Long id;

nessun errore lanciato. Voglio generare una chiave primaria univoca per tabella su oracle db.

È stato utile?

Soluzione

@GeneratedValue (strategy = GenerationType.TABLE) indica al provider JPA di utilizzare una tabella per ottenere gli ID quando si inseriscono entità appena create nel database.

Quando si utilizza Hibernate come provider, ciò comporterà una tabella hibernate_sequences che ha due colonne: il nome dell'entità e l'identità massima già assegnata a questa entità. Qui, sembra che Hibernate non riesca a ottenere l'ID successivo da esso per la tua entità, ma è difficile dire esattamente perché non hai fornito abbastanza informazioni per quello.

Quindi, potresti fornire l'intero stacktrace? Inoltre, attivare la registrazione con la proprietà hibernate.show_sql impostata su true e impostare il livello di registro log4j.logger.org.hibernate.SQL = DEBUG . Unisci il registro alla tua domanda, se possibile.

Forse controlla solo di aver configurato il hibernate.dialect corretto per Oracle. In realtà, unisciti alla tua configurazione di ibernazione, se possibile.

PS: il "tradizionale" il modo per generare PK con Oracle è usare le sequenze (puoi lasciare che Hibernate indovini la migliore strategia per il tuo tipo di database usando GenerationType.AUTO o forzarlo usando SEQUENCE ) ma io ' Suppongo che desideri che la struttura dei dati risultante sia indipendente dal database. In caso contrario, suggerirei invece di seguire le sequenze.

MODIFICA: risposta a un commento dell'OP su GenerationType.AUTO . In effetti, il valore predefinito è una singola sequenza globale chiamata hibernate_sequence e questo potrebbe essere un problema. Ma, con l'installazione mostrata di seguito, puoi usare GenerationType.AUTO e comunque controllare il nome della sequenza per i casi in cui il database utilizza sequenze:

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;

In altre parole, è possibile utilizzare un nome di sequenza diverso per ogni tabella senza perdere la portabilità.

Altri suggerimenti

Esistono 4 strategie per la generazione automatica in JPA:

  • Auto
  • Identità
  • Sequenza
  • Tabella

Per l'annotazione della chiave primaria di generazione automatica Oracle, Sequenza e Tabella sono le tue scelte. La logica di base è definire prima un generatore, utilizzare rispettivamente @SequenceGenerator o @TableGenerator , quindi utilizzare il generatore come attributo in @GeneratedValue .

Questo è un esempio di come utilizzare la strategia di sequenza:

  @Id
  @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
  private long id;

Ecco un esempio di come utilizzare la strategia della tabella:

  @Id
  @TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1 )
  @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN")
  private long id;

Se nessun generatore specificato nell'annotazione @GeneratedValue , la scelta rimarrà all'implementazione dell'APP.

Se si sta lavorando su un database con tabelle esistenti, assicurarsi di avere la sequenza o la tabella definita nel database prima di eseguire l'applicazione. Il generatore di tabelle dovrà inoltre inserire una riga nella tabella prima che l'annotazione @GeneratedValue funzioni correttamente.

Ecco un tutorial su come configurare la generazione automatica della chiave primaria nel database JPA per Oracle .

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