NHibernate сопоставление "один к одному", где данные второй таблицы могут быть нулевыми

У меня есть существующая база данных с таблицей Transactions. Я добавил новую таблицу под названием TransactionSequence, где каждая транзакция будет иметь в итоге только одну запись. Мы используем таблицу последовательностей для подсчета транзакций для данной учетной записи. Я сопоставил это как взаимно однозначное отображение, где TransactionSequence имеет первичный ключ TransactionId.

Ограничение заключается в том, что вместо триггера в таблице транзакций нет обновлений отмененных или размещенных транзакций.

Итак, когда последовательность вычисляется и транзакция сохраняется, NHibernate пытается отправить обновление транзакции, например "UPDATE Transaction SET TransactionId =? WHERE TransactionId =? '. Но это не удается из-за триггера. Как настроить отображение, чтобы NHibernate не попытался обновить таблицу транзакций при вставке новой таблицы TransactionSequence?

Отображение транзакций:

<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>

И отображение последовательности:

<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>

Любая помощь будет принята с благодарностью...

Ответ 1

Индивидуальное сопоставление в nhibernate не работает так, как вы думаете. Он сконструирован так, что у вас есть два класса, которые при сохранении их соответствующих таблиц имеют одинаковые первичные ключи.

Однако вы можете заставить его работать, но это не очень. Я покажу вам, как затем предложить некоторые альтернативы:

В вашей транзакции hbml:

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

В вашей последовательности html:

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

Это должно делать то, что вы хотите. Обратите внимание на свойство-ref.

Следующий вопрос, который вы собираетесь опубликовать, - спросить, как вы получаете ленивую нагрузку на ассоциации "один к одному". Ответ в том, что вы не можете... ну, можете, но это, вероятно, не сработает. Проблема в том, что у вас есть внешний ключ в таблице последовательности, что означает, что nhibernate должен ударить по базе данных, чтобы узнать, существует ли цель. Затем вы можете попробовать сыграть с ограничено = "true/false", чтобы увидеть, можете ли вы убедить его лениво загрузить ассоциацию "один к одному".

В целом, это приведет к полной трате времени.

Я предлагаю либо:

  • У вас есть две ассоциации "один-два".
  • Имейте ассоциацию "много-к-одному" с коллекцией на другом конце.

Это сэкономит вам много головных болей в долгосрочной перспективе.

Ответ 2

Оказывается, что для моей ситуации лучше всего работало сопоставление <join table>. Я просто должен был удостовериться, что я сделал свойства, которые пришли со второй таблицы, были типы с нулевым значением, или это сделало бы вставку для сохранения, даже если ничего не изменилось. Поскольку мне не нужна ленивая загрузка для второго стола, это отлично работает. Я уверен, что я мог бы получить парные сопоставления "много-к-одному" для работы, но он не был интуитивным и выглядел более сложным, чем параметр таблицы соединений, однако <join table> доступен только в NHibernate 2.0 и выше.