Однозначное отображение NHibernate, когда данные второй таблицы могут быть нулевыми - PullRequest
11 голосов
/ 28 октября 2008

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

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

Итак, когда последовательность вычисляется и транзакция сохраняется, NHibernate пытается отправить обновление транзакции, например «UPDATE Transaction SET TransactionId =? ГДЕ 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>

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

Ответы [ 2 ]

15 голосов
/ 29 октября 2008

Отображение один в один в 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 должен попасть в базу данных, чтобы увидеть, существует ли цель. Затем вы можете попробовать поэкспериментировать с constrained = "true / false", чтобы посмотреть, сможете ли вы убедить его лениво загрузить однозначную ассоциацию.

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

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

  1. Имейте две ассоциации многие-к-одному.
  2. Имейте связь многих с одним с коллекцией на другом конце.

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

2 голосов
/ 29 октября 2008

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

...