Domanda

Ho cercato di fare i conti con l'attributo inversa di Hibernate, e sembra essere solo una di quelle cose che è concettualmente difficile.

Il succo che ottengo è che quando si ha un controllante (ad es Parent) che ha una collezione di oggetti figlio utilizzando un uno-a-molti la mappatura, l'impostazione inverse = true sulla mappatura dice a Hibernate che 'l'altro lato (il Bambino) ha la responsabilità di aggiornarsi per mantenere il riferimento chiave esterna nella sua tabella'.

In questo modo sembra avere 2 vantaggi quando si tratta di aggiungere i bambini alla raccolta nel codice, e quindi salvare la Capogruppo (con cascata tutti insieme): si salva un colpo inutile sul database (perché senza set inversa, Hibernate pensa che ha due posti per aggiornare il rapporto FK), e secondo i documenti ufficiali :

  

Se la colonna di un    associazione è dichiarata   NOT NULL, NHibernate può causare   vincolo violazioni quando crea   o aggiorna l'associazione. Impedire   questo problema, è necessario utilizzare un   associazione bidirezionale con il   molti valutate fine (l'insieme o in borsa)   contrassegnato come inverse = "true".

Questo sembra tutto per dare un senso finora. Quello che non capisco è questo:? Quando si non desiderano utilizzare inverse = true su una relazione uno-a-molti

È stato utile?

Soluzione

Come dice Matthieu, l'unico caso in cui non si vorrebbe impostare inverse = true è dove non ha senso per il bambino di essere responsabile per l'aggiornamento stesso, come ad esempio nel caso in cui il bambino non è a conoscenza di suo genitore.

Consente di cercare un mondo reale, e non ad esempio affatto forzato:

<class name="SpyMaster" table="SpyMaster" lazy="true">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
  <set name="Spies" table="Spy" cascade="save-update">
    <key column="SpyMasterId"/>
    <one-to-many class="Spy"/>
  </set>
</class>

<class name="Spy" table="Spy" lazy="true">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
</class>

Spymasters possono avere delle spie, ma spie mai sapere chi è il loro capo delle spie è, perché non abbiamo incluso la relazione molti-a-uno nella classe spia. Inoltre (comodamente) una spia può girare canaglia e così non ha bisogno di essere associato ad un capo delle spie. Siamo in grado di creare entità come segue:

var sm = new SpyMaster
{
    Name = "Head of Operation Treadstone"
};
sm.Spies.Add(new Spy
{
    Name = "Bourne",
    //SpyMaster = sm // Can't do this
});
session.Save(sm);

In questo caso si dovrebbe impostare la colonna FK per essere annullabile perché l'atto di sm risparmio sarebbe inserire nella tabella spymaster e la tabella della spia, e solo dopo che sarebbe poi aggiornare la tabella Spy per impostare l'FK. In questo caso, se dovessimo impostare inverse = true, l'FK sarebbe mai aggiornato.

Altri suggerimenti

Nonostante la risposta di alto votato accettato, ho un altro risposta.

Si consideri un diagramma delle classi con queste relazioni:

Parent => list of Items
Item => Parent

Nessuno mai ha detto, che la voce => relazione padre è ridondante alla relazione padre => Articoli. Un elemento potrebbe fare riferimento a qualsiasi genitore.

Ma nell'applicazione, si sa che i rapporti sono ridondanti . Voi sapete che i rapporti non devono essere conservati separatamente nel database. Così si decide di riporlo in un chiave singola esteri , indicando dalla voce alla Capogruppo. Questa informazione minima è sufficiente per costruire la lista e il riferimento posteriore.

Tutto quello che devi fare per mappare questo con NH è:

  • utilizzare la stessa chiave esterna per entrambe le relazioni
  • dire che uno NH (elenco) è ridondante all'altra e potrebbe essere ignorato quando memorizzare l'oggetto. (Questo è ciò che in realtà NH fa con inverse="true")

Questi sono i pensieri che sono rilevanti per l'inversa. Nient'altro. E non è una scelta, c'è un solo modo di una corretta mappatura.


La spia Problema : Si tratta di una discussione completamente diversa se si vuole sostenere un riferimento dal Item alla Capogruppo. Questo è fino al vostro modello di business, NH non prende alcuna decisione in questo. Se una delle relazioni manca, c'è naturalmente nessuna ridondanza e nessun uso di inversa.

Abuso: Se si utilizza inverse = "true" su una lista che non ha alcuna ridondanza nella memoria, semplicemente non vengono memorizzati. Se non si specifica l'inverso = "true" se deve esserci, NH può memorizzare le informazioni ridondanti per due volte.

Se si desidera avere un'associazione unidirezionale vale a dire che i bambini non possono accedere alla Capogruppo. Se è così, colonna FK dovrebbe essere NULLABLE perché i bambini saranno salvati prima che il genitore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top