2010-03-05 13 views
7

Ho qualche codice:Come viene generato il mio id con JPA usando Hibernate con il dialetto Oracle 10g?

@Id 
@SequenceGenerator(name = "SOMETHING_SEQ") 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOMETHING_SEQ") 
@Column(name = "SOMETHING", nullable = false) 
private Long id; 

Come è hibernate fornendo il mio id?

Vedo nel mio database una singola sequenza denominata "hibernate_sequence" e nessun'altra "tabella speciale" di ibernazione.

risposta

9

In realtà, qui il tuo SOMETHING_SEQ è il nome della sequenza è stata configurata da qualche parte nella configurazione di ibernazione. E hibernate_sequence è il nome della sequenza nel database. Nella configurazione sarà simile al seguente,

<sequence-generator name="SOMETHING_SEQ" 
    sequence-name="hibernate_sequence" 
    allocation-size="<any_number_value>"/> 

È possibile saltare completamente questa configurazione utilizzando invece l'annotazione. Quindi l'annotazione @SequenceGenerator dovrebbe fornire pochi altri parametri. Di seguito è riportato l'esempio.

@SequenceGenerator(name="SOMETHING_SEQ", sequenceName="hibernate_sequence", allocationSize=10) 

Per esempio i molteplici classi di entità farebbe qualcosa di simile qui di seguito,

@Entity 
public class Entity1 { 
    @Id 
    @SequenceGenerator(name = "entity1Seq", sequenceName="ENTITY1_SEQ", allocationSize=1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity1Seq") 
    @Column(name = "ID", nullable = false) 
    private Long id; 

    ... 
    ... 

} 

@Entity 
public class Entity2 { 
    @Id 
    @SequenceGenerator(name = "entity2Seq", sequenceName="ENTITY2_SEQ", allocationSize=10) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity2Seq") 
    @Column(name = "ID", nullable = false) 
    private Long id; 

    ... 
    ... 

} 
+0

Grazie. Ma nel mio caso, in che modo l'ibernazione fornisce il mio id? Come quando salgo la mia entità con un valore nullo per il mio ID lungo, magicamente viene inserito automaticamente. È tramite qualche tabella speciale, o usando quel hibernate_sequence? O..? – JavaRocky

+0

Usando 'hibernate-seq', e ovviamente quando hai detto che Hibernate lo genera, non devi fornirtelo tu stesso. O anche se fornisci qualche valore per dire, quel valore verrebbe sovrascritto. –

+0

Stai dicendo che più entità condividono la stessa sequenza di ibernazione? – JavaRocky

0

In Oracle non si dispone del tipo auto_increment come in MySQL. Quindi, per generare una colonna auto_increment devi usare una sequenza.

Questo è un esempio di come è possibile ottenere ciò.

create table test (id number, testdata varchar2(255)); 


create sequence test_seq 
start with 1 
increment by 1 
nomaxvalue; 

create trigger test_trigger 
before insert on test 
for each row 
begin 
select test_seq.nextval into :new.id from dual; 
end; 

Così si crea una sequenza e si utilizza un trigger prima che ogni riga venga inserita per aggiungere il proprio ID.

Così ibernazione deve essere fare qualcosa di simile, o invece di utilizzare il grilletto facendo

insert into test values(test_seq.nextval, 'no trigger needed!'); 

Nota: Esempio tratto da here

+0

Grazie. Infatti Oracle non ha la capacità auto_increment. Tuttavia, quando salgo la mia @ Entity, lascio i miei campi @Id null. Che quindi EntityManager in qualche modo genera un ID da qualche parte e lo inserisce. Lo so quando abilito l'output SQL alla console. Quindi, tornando alla mia domanda, da dove viene questo ID con la mia configurazione? – JavaRocky

+0

utilizza sicuramente la sequenza. Ora se usa il trigger, o l'inserto in linea, configura l'ibernazione per mostrare sql o controlla se è stato generato un trigger – Lombo

+0

Hibernate non usa un trigger, ottiene solo il 'nextval' in insert. –

4

Al fine di nominare la sequenza è necessario impostare la sequenceName nel @SequenceGenerator annotazione:

@GeneratedValue(name="gen", strategy = GeneratorType.SEQUENCE) 
@SequenceGenerator(name="gen", sequenceName="Sequence_Name", allocationSize = 1) 
@Id 
public Long getId() 
{ 
    // ... 
} 

Di nota, se stai utilizzando un generatore preesistente, il tuo allocationSize deve corrispondere alla dimensione di allocazione di quel generatore.

4

Come è l'ibernazione che fornisce il mio ID?

Beh, ti ha detto in modo esplicito il motore APP per generare identificatore automaticamente (con la @GeneratedValue annotazione) utilizzando una strategia di tipo SEQUENCE indicando che una sequenza banca dati dovrebbe essere utilizzato per generare l'identificatore. Nel caso ti interessi, le sequenze sono oggetti specifici del database (ad esempio Oracle) che possono essere utilizzati per generare numeri interi univoci.

vedo nel mio database c'è una singola sequenza di nome 'hibernate_sequence'

non ha utilizzato l'elemento sequenceName di annotazione nel vostro @SequenceGenerator per specificare il nome dell'oggetto sequenza di database da utilizzare in modo Hibernate creato un oggetto sequenza predefinito durante la generazione dello schema (che per impostazione predefinita è hibernate_sequence). Per specificare una sequenza, farlo in questo modo:

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_entity_seq_gen") 
@SequenceGenerator(name = "my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ") 
private Long id; 
+0

Altrettanto buona risposta – JavaRocky

Problemi correlati