Mappage NHibernate un à un où les données de la seconde table peuvent être nulles

StackOverflow https://stackoverflow.com/questions/244812

  •  05-07-2019
  •  | 
  •  

Question

J'ai une base de données existante contenant la table Transactions. J'ai ajouté une nouvelle table appelée TransactionSequence dans laquelle chaque transaction n'a finalement qu'un seul enregistrement. Nous utilisons la table de séquence pour compter les transactions pour un compte donné. J'ai mappé ceci en tant que mappage un-à-un où TransactionSequence a une clé primaire de TransactionId.

La contrainte est qu’il existe un déclencheur à la place de la table des transactions qui ne permet pas les mises à jour des transactions annulées ou comptabilisées.

Ainsi, lorsque la séquence est calculée et que la transaction est enregistrée, NHibernate tente d’envoyer une mise à jour de la transaction telle que 'UPDATE Transaction SET TransactionId =? O TransactionId =? '. Mais cela échoue à cause du déclencheur. Comment puis-je configurer mon mappage pour que NHibernate n'essaye pas de mettre à jour la table Transaction lorsqu'un nouveau tableau TransactionSequence est inséré?

Mappage de transaction:

<class name="Transaction" table="Transaction" dynamic-update="true" select-before-update="true">
    <id name="Id" column="ID">
        <generator class="native" />
    </id>

    <property name="TransactionTypeId" access="field.camelcase-underscore" />
    <property name="TransactionStatusId" column="DebitDebitStatus" access="field.camelcase-underscore" />

    <one-to-one name="Sequence" class="TransactionSequence" fetch="join"
                 lazy="false" constrained="false">      
    </one-to-one>
</class>

Et le mappage de séquence:

<class name="TransactionSequence" table="TransactionSequence" dynamic-update="true">
    <id name="TransactionId" column="TransactionID" type="Int32">
        <generator class="foreign">
            <param name="property">Transaction</param>
        </generator>
    </id>

    <version name="Version" column="Version" unsaved-value="-1" access="field.camelcase-underscore" />

    <property name="SequenceNumber" not-null="true" />

    <one-to-one name="Transaction" 
                class="Transaction" 
                constrained="true" 
                foreign-key="fk_Transaction_Sequence" />

</class>

Toute aide serait grandement appréciée ...

Était-ce utile?

La solution

Le mappage un à un dans nhibernate ne fonctionne pas comme vous le pensez. Il est conçu pour que vous ayez deux classes qui, lorsqu'elles sont persistées dans leurs tables correspondantes, ont les mêmes clés primaires.

Cependant, vous pouvez le faire fonctionner, mais ce n’est pas beau. Je vais vous montrer comment proposer des alternatives:

Dans votre transaction hbml:

<one-to-one name="Sequence" class="TransactionSequence" property-ref="Transaction"/>

Dans votre séquence html:

<many-to-one name="Transaction" class="Transaction" column="fk_Transaction_Sequence" />

Cela devrait faire ce que vous voulez. Notez la propriété-ref.

La prochaine question que vous allez publier consistera à vous demander comment vous pouvez vous détendre en chargeant des associations individuelles. La réponse est que vous ne pouvez pas ... eh bien, vous le pouvez, mais cela ne fonctionnera probablement pas. Le problème est que vous avez votre clé étrangère sur la table de séquence, ce qui signifie que nhibernate doit accéder à la base de données pour voir si la cible existe. Ensuite, vous pouvez essayer de jouer avec constrained = & "True / false &"; pour voir si vous pouvez le persuader de charger paresseusement l'association one-to-one.

Tout compte fait, votre temps sera totalement perdu.

Je suggère soit:

  1. Ayez deux associations plusieurs-à-un.
  2. Établissez une association plusieurs-à-un avec une collection à l'autre bout.

Cela vous évitera beaucoup de maux de tête à long terme.

Autres conseils

Il s’est avéré que, dans mon cas, un mappage <join table> fonctionnait mieux. Je devais simplement m'assurer que les propriétés issues de la deuxième table étaient des types nullables, sinon une insertion serait effectuée même si rien n'avait changé. Comme je n'avais pas besoin de chargement paresseux pour la deuxième table, cela fonctionne très bien. Je suis sûr que j’aurais pu obtenir des mappages couplés plusieurs-à-un pour fonctionner, mais cela n’était pas intuitif et semblait plus compliqué que l’option de table de jointure. Cependant, <=> n’est disponible que dans NHibernate 2.0 et versions ultérieures.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top