2010-06-21 3 views
0

Я наблюдаю странное поведение от Fluent nHibernate. У меня есть два объекта, вовлеченных в эту проблему: объект «Страница» и объект «Метаданные». Страница может содержать несколько объектов метаданных, и отображение выполняется таким образом:Свободно nHibernate сбережения null id - листья сироты

'in PageMap 
HasMany(Function(x) x.MetaData).Cascade.All() 
'in MetaDataMap 
References(Function(x) x.Page) 

Проблема возникает при сохранении процесса. Когда я хочу сохранить изменения в объекте страницы, я получаю существующий объект страницы, просматриваю список изменений, а затем используйте Session.Update (Страница) для сохранения значений. Нечеткое поведение заключается в том, что данные сохраняются, но метаданные страницы сохраняются дважды: один раз, как ожидалось, и в другое время с page_id нулевого значения. Однако странно, что это происходит даже тогда, когда я комментирую команду «Обновить», поэтому на самом деле это не обновление, которое заставляет данные сохранять!

Выполнение кода и просмотр данных Я проследил ошибку до той точки, где я использую nHibernate, чтобы получить объект страницы, чтобы использовать его данные. Поэтому, прежде чем я вызову этот метод, база данных вообще не показывает изменений Metdata. После этого я не вижу БД (он занят), но возвращаемая страница содержит любые добавленные метаданные. Метод get выглядит так:

Public Function GetById(ByVal Id As Integer) As Cms.DataTransferObjects.Page Implements IPageManager.GetById 
    Dim session As ISession = NHibernateSessionManagerStore.Instance.GetSession() 
    Dim results As Cms.DataTransferObjects.Page 

    results = session.CreateCriteria(Of DataTransferObjects.Page)() _ 
     .Add(Expression.Like("Id", Id)) _ 
     .UniqueResult(Of DataTransferObjects.Page)() 

    Return results 
End Function 

Таким образом, нет ничего, что могло бы спасти данные.

Может ли кто-нибудь пролить свет на это? Это сводит меня с ума!

Cheers, Matt

ответ

1

Вам не нужно вызывать Update когда экземпляр уже в сессии. NHibernate достаточно умен, чтобы найти все изменения, сделанные на объектах, и сохранить их в базе данных. Чтобы поместить экземпляр в сеанс, вы обычно используете запрос для получения существующих объектов, или Save, чтобы сохранить новый экземпляр. Update полезен только для отдельных экземпляров.

Запись состояния памяти в базу данных называется Flush ing. NH flushes перед фиксацией, но также и перед запросами, чтобы убедиться, что запрос выполняется по фактическим данным (поэтому, если вы установите свойство на «A», вы можете сразу сделать запрос, который фильтрует это свойство «A», я получу ваш экземпляр).

Я не знаю, почему NH сохраняет нулевой внешний ключ. Вы где-то устанавливаете внешний ключ? Вы пытаетесь «повторно использовать» свой экземпляр для чего-то еще?

+0

Спасибо за это - очень полезное объяснение. Как оказалось, я создавал новые осиротевшие объекты в другом месте кода и сбивался с толку, потому что они не были немедленно переданы в БД. Я сомневаюсь, что я бы заметил это без вашего ответа :) –