2009-12-22 5 views
6

Prima i fatti di base: webapp Java, Spring, Hibernate, MySQL.Implementazione di una cronologia dei dati/soluzione di versionamento per un'applicazione basata su Hibernate (con una torsione)

La situazione è che ho un modello di oggetto complesso di ad es. a Car. È composto da molti oggetti (Motore, Pneumatici, ...) con relazioni molti-a-uno e uno-a-molti tra loro.

Ora ci sono molte macchine e ogni tanto qualcuno ispeziona un'auto e crea un rapporto dell'ispezione. Il rapporto fa riferimento alle molte parti che l'auto, mostrando le loro proprietà ecc.

Finora il sistema non ha supportato la possibilità di aggiornare le proprietà dell'auto e delle sue parti una volta che sono state inserite nel sistema. Significa che se un colore del telaio o il numero di pneumatici sono stati cambiati, i vecchi rapporti rifletterebbero questo cambiamento che non è quello che vogliamo.

Bene, ora questa funzione è stata richiesta. Le auto e le loro parti devono essere modificabili e deve essere creata una cronologia delle versioni. I vecchi report devono fare riferimento alle vecchie versioni delle parti e ai loro valori.

Ho guardato "Slowly changing dimensions" e sembra che la versione della macchina e le sue parti potrebbero essere fatte con l'approccio di tipo 6.

La cosa (la torsione) che sto avendo problemi a capire (probabilmente a causa della mia esperienza limitata Hibernate) è questo:

Come posso montare le mie istanze report con Hibernate in modo che essi si riferiscono al versioni corrette di ogni parte dell'auto? I report hanno una data e ogni versione delle parti di auto avrebbe intervalli di date quando erano validi, quindi credo che potrei farlo con alcuni HQL/SQL complessi. Ma c'è un modo più semplice e automatico di farlo con Hibernate?

risposta

1

Ho usato l'approccio che suggerisci (Tipo 6) con Hibernate e ha funzionato bene per me. Le query per i report sono diventate un po 'più complicate, ma non tanto, poiché la stessa clausola era necessaria per tutte le query (es.' E: reportTime> = x.startTime e (: reportTime < x.endTime o x.endTime è null) ').

Ho creato un'interfaccia e una classe base (l'interfaccia era necessaria solo per le sottoclassi temporali il cui genitore non era temporaneo) per le entità che supportavano questo approccio con 2 proprietà (es. StartTime e endTime) e una classe base per DAO funzionanti con entità temporali che avevano spesso bisogno di alcune funzionalità. Le cose che ho messo in questa base DAO:

  1. Prevenire modifiche alle istanze di cui startTime era passato (tranne l'impostazione del endTime ad un tempo futuro)
  2. Chiusura automatica (vale a dire il riempimento del endTime) l'istanza precedente se una nuova è stata aggiunta un'istanza (ad es. oldInstance.endTime = newInstance.startTime)
  3. Aggiunta della clausola standard per selezionare le entità correnti al momento della query alle query HQL.
  4. Trattare con i duplicati se per qualche motivo due istanze valide/versioni sono stati trovati in un momento nel tempo (ho ordinato le mie domande da 'startTime disc' e ha preso solo il primo restituito)

L'unica parte in cui ho trovato che era davvero complicato lavorare con semplici query SQL eseguite anche contro il database, dove erano necessarie le clausole extra sulle tabelle unite o in sottoselezioni.

+0

Questo è stato praticamente l'approccio che abbiamo preso. – Janne

1

MySQL supporta triggers. Imposta un trigger in modo che ogni volta che viene modificata una riga, il trigger copia la riga in una tabella "archivio", insieme a un timestamp. In questo modo, vengono mantenute tutte le precedenti versioni dei dati, a cui è possibile eseguire i report.

6

Puoi dare un'occhiata a JBoss envers per il controllo delle versioni dei tuoi oggetti. Non sono sicuro che sia adatto al tuo caso, ma dai un'occhiata.

+0

Grazie per il suggerimento. Envers sembra molto utile ma non si adatta abbastanza alla situazione. Buono a sapersi, esiste comunque. – Janne

Problemi correlati