2012-11-29 17 views
10

Ho un insieme di entità che si connettono tra loro formando un ciclo cioè, l'entità padre P ha due relazioni uno-a-molti con due entità figlio C1 e C2 e ciascuna uno di questi ha una relazione uno-a-molti con un'altra entità A. Entità A realizza l'associazione di queste entità (C1, C2) e definisce gli attributi della relazione (non è solo una tabella di join). Tutte le relazioni sono navigabili in entrambe le direzioni.
domain objects
alla seguente domanda sorge da questo progetto: Quale dovrebbe essere la strategia di cascata in modo tale entità A può essere persistente/fusione, dato che sempre richiama le operazioni di entità gestore sull'entità radice P? A dovrebbe essere una cascata raggiungibile da entrambi i percorsi?JPA + Hibernate - Cicli nelle relazioni di entità - Strategia in cascata

Considerazioni: Sembra che se l'applicazione sceglie di fornire un solo percorso a cascata, possono essere presenti scenari che generano una TransientObjectException. Se fornisce entrambi i percorsi, questi percorsi devono eseguire il ciclo completo, ad esempio C1 potrebbe essere tentato di essere salvato tramite A.

Versioni: JPA 2.0, Hibernate core 4.1.7, hibernate-jpa-2.0-api 1.0 .1

risposta

3

Posso darti i miei 2 centesimi, scusa se la mia risposta è un po 'lunga.

Se si dispone di un conflitto a catena di questo tipo, potrebbe essere dovuto al fatto che l'approccio a catena o il modello di dominio non sono ben definiti. Sarei attento a generalizzare una strategia a cascata su un grafico complessivo o su un insieme di elementi non correlati.

Il mio consiglio sarebbe che la strategia a cascata dovrebbe essere impiegata solo su un insieme di dati fortemente legati tra loro, e dello stesso tipo, come per una classe e le sue classi interne (private) nel mondo java. Anche la relazione tra la classe madre e i suoi figli dovrebbe essere esclusiva (in UML è chiamata Associazione non condivisa).

Ovviamente si può fare diversamente (tutti noi possiamo essere pigri), ma alla fine è possibile creare una rete di accoppiamento tra il proprio singolo flusso di persistenza (o configurazione di persistenza) e il flusso aziendale. Dovrai gestire molte eccezioni e fare molta logica di configurazione attorno alla strategia a cascata che hai precedentemente messo (salva, aggiorna, cancella).

L'approccio estremo sarebbe che alcuni potrebbero voler salvare solo un oggetto radice di grandi dimensioni. Perchè no? il resto "dovrebbe persistere in cascata". Ma in realtà, questo potrebbe limitare seriamente la manutenibilità del tuo sistema. Inoltre, potresti dover gestire lo stato del tuo grande grafico in memoria, durante il caricamento, il salvataggio e l'unione.

Se si esegue un'applicazione Web o qualsiasi applicazione client-server, il flusso di lavoro Web dovrebbe essere in grado di salvare un set limitato di oggetti a ogni richiesta senza dover salvare tutto dall'elemento radice. So che non rispondo direttamente alla tua domanda. Quindi, torniamo al tuo esempio:

Diciamo che P è un banco e C1 e C2 sono due client e A è un prodotto.

Ho due risposte facili: 1) Ogni livello può essere salvato separatamente senza alcuna sovrapposizione. Ma può essere fatto all'interno della stessa transazione, e nello stesso DAO o no se lo si desidera.

2) P e C "può" essere collegato in cascata. Ma A deve essere salvato in un diverso flusso di lavoro.

Questo mi ricorda un capitolo di Peter Coad dove si parla di un "dominio Analysis Driven": http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf

Questo capitolo spiega come diversi oggetti in un grafico possono essere separati in diversi archetipi. Il workflow di persistenza non dovrebbe essere lo stesso tra i dati transazionali e una descrizione, o una "cosa". Questo può aiutare a mettere in atto una migliore strategia a cascata:

The four archetypes of Peter Coad are: 
- Is it a moment or interval? 
- Is it a role played? 
- Is it a catalog-entry-like description? 
- Otherwise, it's a party, place, or thing. 

spero che aiuta.

3

Generalmente una buona idea è quella di cascata solo in associazioni strette e solo nella direzione genitore-> figlio (o proprietario-> di proprietà). Nel tuo caso sarebbe probabilmente P->C1 e P->C2. Dal momento che A non ha un genitore ovvio, dovrebbe essere salvato separatamente. Questo può essere fatto come @etienno menzionato nel DAO in una singola transazione insieme a P (e C1, C2). Non conosco il tuo modello di dominio, ma forse anche lo A è a livello concettuale un'entità separata, nel qual caso un salvataggio separato è ancora più giustificato.

Il collegamento in cascata a molti oggetti che non sono strettamente correlati può a lungo termine rendere l'intero grafico, quando diventa più grande, ingestibile.

In situazioni come questa è sempre utile porre la domanda "come faresti senza Hibernate". Nel tuo caso probabilmente dovresti prima salvare P, poi C1, C2 e poi A. AFAIK JPA/Hibernate non fornisce alcun modo esplicito per applicare tale ordine, quindi alcune cose devono essere eseguite manualmente dall'utente.

Problemi correlati