2011-09-11 14 views
7

In un progetto basato su Spring/Hibernate, abbiamo una relazione uno-a-molti tra due entità. Le operazioni richieste sono:Le associazioni bidirezionali in letargo dovrebbero essere evitate?

  • trovare il genitore del bambino;
  • trovare i figli dei genitori;
  • quando il genitore viene rimosso, dobbiamo anche rimuovere i bambini;
  • creazione di massa dei bambini.

Abbiamo inventato due modi per implementarlo.

  1. Bidirectional association: entità bambino ha @ManyToOne colonna che lo collega al genitore, e il genitore ha @OneToMany collezione pigro-caricato dei bambini. Tutte le operazioni di cui sopra possono essere eseguite nel modello:

    child.getParent(); 
    parent.getChildren(); //lazy loading 
    session.delete(parent); //cascade removal of the children does the trick here 
    session.save(parent); //cascade persist created the children 
    
  2. unidirezionale associazione: entità bambino ha @ManyToOne colonna che lo collega al genitore, ma il genitore non avere alcun collegamento per i bambini. La maggior parte delle operazioni devono essere eseguite in modalità di servizio:

    child.getParent(); //still in the model 
    Collection<Child> findChildren(Parent parent); //service method in ChildService 
    void deleteChildren(Parent parent); //service method in ChildService 
    void createChild(Parent parent, ... childAttributes); //service method in ChildService invoked for each new child. 
    

Il primo approccio sembra essere più facile da implementare (è possibile riutilizzare Hibernate funzionalità a cascata), ma alcuni di noi vedere le associazioni bidirezionali come una potenziale causa di problemi .

Quale dovrebbe essere una scelta di design migliore? Ci sono problemi noti, prestazioni o design, creati dall'approccio bidirezionale?

+0

Sei a conoscenza di una fonte che spiega come far funzionare lazyloading? Ho avuto problemi con questo in un progetto JSF. –

+1

"alcuni di noi vedono le associazioni bidirezionali come una potenziale causa di problemi" - puoi citare questi potenziali problemi? –

risposta

3

Se le query fanno la stessa cosa delle query eseguite dietro la scena da Hibernate quando fa pigre-caricano i bambini, non vedo che cosa ottieni semplicemente non usando un'associazione OneToMany.

Se sai cosa stai facendo e ciò che ogni metodo chiama sulla tua entità significa in termini di query al database, non dovresti avere alcun problema con le raccolte mappate. A volte è consigliabile attraversarli, a volte è meglio usare una query ad-hoc per evitare troppi round-trip nel database. La chiave è capire cosa succede.

Avere un'associazione può anche essere molto utile solo per essere in grado di navigare attraverso di essa nelle query HQL, non necessariamente per chiamare il getter associato.

0

Finché ci si trova in una situazione in cui il caricamento lento funziona davvero per voi, non ho riscontrato un problema reale con le relazioni bidirezionali. Una volta ho lavorato su un'applicazione Flex in cui è stato utilizzato Hibernate e le relazioni bidirezionali spesso causavano il download dell'intero database quando i dati venivano serializzati sul client.

YMMV

0

La risposta da @JB Nizet dice quasi tutto, solo una cosa: Guardando i campioni metodo di chiamata hai postato, il metodo bidirezionale probabilmente rendere il codice logica di business un po 'più leggibile.

-1

Sì, Ciò dovrebbe essere evitato il più possibile. se pensi davvero, questo è il tuo requisito, quindi usa solo bidirezionale. per esempio. Emp e Dept, ogni emp ha un reparto, ma il reparto ha molti dipendenti. emp deve conoscere il suo dipartimento, ma non è obbligatorio che il dipartimento sappia anche il proprio dipartimento.

+1

Questo sembra più un commento, piuttosto che una risposta. – mattias

Problemi correlati