Refactor un vecchio modello di una modifica LastUser su ogni oggetto?

2

Ho un requisito software, che deve memorizzare l'utente che ha apportato l'ultima modifica a un altro oggetto, per ogni oggetto (si supponga che tutti gli oggetti siano già mappati e in un BD).

Quindi abbiamo il ParamBase un oggetto che contiene i dati di base per ogni oggetto, questa sarà una super classe, ogni altro parametro nel sistema erediterà questa classe, (usando @MappedSuperClass)

@MappedSuperclass
ParamBase {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Version
    private Long version;

    @Temporal(value = TemporalType.TIMESTAMP)
    private Date timeStampLastModification;

    @Column
    private User userOfLastModification;
    //constructors, getter setters, other stuff, etc
} 

L'oggetto User, questo rappresenterà l'utente, anche mappato in un BD, per ora è solo semplice Oggetto mappato come Entità, tutti gli altri Parametri dovranno memorizzare questo Utente in un campo.

@Entity
User {
   //User stuff, cons, get, seters, etc
}

@Entity
Country extends ParamBase {
    //This class extends ParamBase so will have a field to hold the 
    //userOfLastModification
}

In un EJB ho una logica aziendale che funzionerà con diverse operazioni e oggetti, quando in questo caso un parametro viene aggiornato, la userSession (assegnata all'accesso) aggiornerà il campo userOfLastModification.

IL PROBLEMA: Tutti gli oggetti avranno una relazione con User, quindi tutti gli altri oggetti hanno un campo mappato userOfLastModification_id, questo crea una dipendenza enorme di tutti i clases all'utente. Per darti un'idea, basta un'immagine su un diagramma di Entity Relation ER, tutte le tabelle relative a un singolo User Table, è un casino !!!

IL REFATTORE !: Penso che questo modello sia sbagliato, penso che rompa l'equilibrio del design del software Non penso che sia necessario creare una relazione tra tutte le tabelle / oggetti su una tabella (Utente) per soddisfare questo requisito, mi piacerà qualche feedback o ides su come: 1. Spiega l'errore di progettazione, se ce n'è uno? (Penso sempre che potrei sbagliarmi, e non c'è alcun problema con questo)

  1. C'è un modo migliore per farlo?

Grazie per il tuo aiuto!

    
posta nicoLinjava 21.01.2014 - 14:27
fonte

3 risposte

1

Da una prospettiva di progettazione del database, c'è niente di sbagliato con il monitoraggio dei tuoi utenti con una singola tabella tramite un campo di riferimento comune dove applicabile. Potresti non avere un indice calcolato su ogni singola tabella, ma questo è un dettaglio di implementazione piuttosto che un requisito di progettazione.

Sul lato Java, tuttavia, l'intuizione è corretta. Probabilmente non vuoi che ogni oggetto contenga un riferimento completo a user . Invece, includere un campo standard con una convenzione di denominazione comune e trattare il riferimento utente semplicemente come testo. Quindi, invece di

@MappedSuperclass
ParamBase {
    private User userOfLastModification;
} 

avresti fatto qualcosa del tipo:

@MappedSuperclass
ParamBase {
    private String userOfLastModification;
} 

Spargi solo un oggetto User effettivo quando ti servono i vari punti dati, ad esempio se stai traducendo la chiave interna di un utente in un nome visualizzato.

    
risposta data 21.01.2014 - 15:01
fonte
1

Mi piace la risposta di DougM su come gestire in Java (una stringa per l'utente che ha aggiornato per ultimo il record della tabella). L'obiettivo qui è gestirlo all'interno della tua app. Tuttavia, non penso che abbiamo abbastanza informazioni qui sull'ampiezza degli aggiornamenti di tracciamento in questo sistema, specialmente dal punto di vista del database. Hai intenzione di garantire che tutte le modifiche ai record si verifichino solo nell'app?

Questi sono requisiti diversi:

  1. Tieni traccia di ogni modifica apportata da un utente a ogni record di tabella.
  2. Tieni traccia di ogni modifica apportata a ciascun record della tabella indipendentemente da chi e come è stato aggiornato.
  3. Consenti solo agli utenti (nella tabella utenti) di apportare modifiche ai record e tracciare l'ultimo.

Le tue esigenze sembrano corrispondere a # 3. Non ne so abbastanza della tua app. Potrebbe essere esattamente ciò di cui hai bisogno. In questo caso, applicherei l'integrità referenziale tra la tabella utente e tutte le altre tabelle. In questo modo non importa se la tua app o qualche altra fonte apporta modifiche ai dati, devono fare riferimento a un record di account utente.

La soluzione al # 1 consiste nel mettere semplicemente una sorta di nome utente nel campo "UpdateUser". Gli utenti potrebbero essere cancellati dalla tabella degli utenti, ma alla tua app non interesserà andare avanti. Un sacco di flessibilità qui. Il cliente può piacere o meno.

Ci sono situazioni in cui # 2 potrebbe essere il migliore. Se hai effettuato un'acquisizione di Acme Company, potresti importare tutti questi dati e rendere l'utente="Acme Import". Potrebbe esserci qualche lavoro notturno in esecuzione che porta dati da una fonte esterna, quindi chiamalo "Aggiornamento notturno".

Naturalmente è necessario prendere in considerazione le prestazioni e la facilità di gestione del sistema. Questa non è una risposta tanto esatta a come dovresti farlo, ma come dovresti fare per trovare una soluzione e alcune cose da considerare. Potrebbe essere necessario chiarire i requisiti in base alle conoscenze del tuo cliente in merito a sicurezza, registrazione e gestione dei dati.

    
risposta data 21.04.2014 - 18:42
fonte
-4

Il refactoring con l'approccio di DougM per gestirlo con una stringa Java ha avuto il miglior risultato possibile visto che solo getter e setter sono stati modificati, con una piccola quantità di efford.

    
risposta data 01.10.2014 - 22:26
fonte