2013-03-20 20 views
7

Ho un'app basata su Hibernate in produzione, con un database di grandi dimensioni. Ho bisogno di aggiungere il controllo a due entità (due tabelle) in questa applicazione, e ho deciso di andare con Envers.Aggiunta di Envers a un database esistente

Per ogni INSERT, UPDATE o DELETE, Envers aggiunge un nuovo record alla tabella di controllo dell'entità.

Se avessi il supporto di Envers dall'avvio dell'applicazione, le tabelle di controllo verrebbero compilate al momento della creazione delle entità (INSERT).

La documentazione di Envers è molto sottile e non menziona nulla sull'aggiunta di Envers a un'applicazione esistente.

Se aggiungo semplicemente il supporto Envers e creo le rispettive tabelle di controllo, inizieranno a essere vuoti, quindi quando AGGIORNO un'entità esistente, Envers aggiungerà un record alla tabella di controllo registrando i nuovi valori, ma perdo il valori precedenti.

Come aggiungere il supporto Envers a un'applicazione con un database esistente?

+0

Hi! Hai risolto il tuo problema? Sto avendo lo stesso problema anche io .. – gipinani

+0

No, ho ceduto su Envers e ho usato INSERT e ON UPDATE trigger di database –

risposta

2

Attualmente non esiste una soluzione integrata per questo.

Il modo "corretto" sarebbe quello di scrivere uno script SQL (o creare manualmente) una revisione "0", insieme ai record di revisione dell'inserto legati a quella revisione per ogni entità esistente.

In realtà, è una funzionalità abbastanza comune, quindi se vuoi contribuire, sarebbe il benvenuto!

+0

Poiché le revisioni sono globali e non locali per un'entità specifica, temo che aggiungendo uno "0" la revisione che riguarda tutte le entità interromperà l'interrogazione per le revisioni precedenti, poiché quando interrogherò per la revisione "0" cercherebbe di caricare l'intero database, non sarebbe un problema? –

+0

@DanielSerodio Adamw è corretto. Devi aggiungere la revisione 0 e iniziare da quella per il tuo database esistente. Come si possono scoprire le revisioni precedenti se al momento non vi è alcun auditing in atto? – RNJ

+0

@RNJ dal momento che hai risposto rapidamente dopo il mio commento sopra, non sono sicuro che tu abbia visto quel commento (sulla revisione globale). Pensi che sarebbe un problema? –

1

È necessario eseguire inserti manuali. Qualcosa di simile

INSERT INTO z_envers_revisions (ID, timestamp, user_id, user_name) values (1, round((sysdate - to_date('19700101','YYYYMMDD')) * 86400000) , 42, 'UserName'); 

INSERT INTO z_Table1(rev, revtype, id, description, name) select 1 as rev, 0 as revtype, id, description, name from Table1; 
INSERT INTO z_Table2(rev, revtype, id, description, name) select 1 as rev, 0 as revtype, id, description, name from Table2; 

ho preceduto le mie tabelle di controllo con az qui per renderlo più breve

0

Per quanto riguarda envers è interessato, il caso d'uso di base è quella di registrare la revisione completa di un'entità (i parametri di noi desidero tramite l'annotazione @Audited). Per il caso che stai menzionando, le nuove entità potrebbero essere aggiunte correttamente, ma per l'esistenza darebbe un problema in quanto non ci sono revisioni presenti nella tabella di audit.

Risolviamo il caso con l'aiuto di uno scenario:

Diciamo che l'entità che abbiamo preso in considerazione è utenti. La tabella che viene creata ora per osservare la cronologia, diciamo, è users_audit. In aggiunta ad esso revinfo sarebbe anche in atto per osservare e registrare tutte le modifiche in un dato record.

Il problema si presenta in primo luogo, perché ogni volta che c'è un aggiornamento, il livello di persistenza non è in grado di trovare un record di revisione. Quindi per risolvere il problema tutte le voci esistenti devono essere presenti nella tabella e la mappatura delle chiavi esterne con la tabella di revinfo non deve essere interrotta. Quindi, due cose devono essere fatte:

  1. inserire i valori temporanei nella tabella revinfo in modo che il rev può fungere da chiave esterna
  2. Copiare i dati dai utenti tabella a users_audit tabella.

Esempio Liquibase file può essere simile a questo:

CREATE TABLE `revinfo` (
     `rev` int(11) NOT NULL AUTO_INCREMENT, 
     `revtstmp` bigint(20) DEFAULT NULL, 
     PRIMARY KEY (`rev`) 
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 

    INSERT INTO `revinfo` (`revtstmp`) select updated_at from users u; 

    SET @position := 0; 

    insert into users_audit (
    rev, 
    revtype, 
    id, 
    name, 
    type, 
    mobile_number, 
    password, 
    parent_id, 
    profile_image_uri, 
    is_active, 
    created_at, 
    updated_at 
    ) select @position := @position +1, 0, 
    id, 
    name, 
    type, 
    mobile_number, 
    password, 
    parent_id, 
    profile_image_uri, 
    is_active, 
    created_at, 
    updated_at from us 
Problemi correlati