2016-04-03 4 views
0

Каково состояние объекта, если оно добавлено с использованием запроса INSERT? И как я могу получить этот объект в тот же сеанс?Использование CreateSQLQuery с запросом INSERT в NHibernate

Вставка объекта с использованием нативного SQL

session.CreateSQLQuery("INSERT INTO table (...) VALUES (...)").ExecuteUpdate()) 

Я знаю его Id, поэтому использовать это для ГЭТ:

sessison.Get<MyObjectType>(id) 

но объект имеет нулевое значение, так как сеанс же и совершить еще находится на рассмотрении. Что я делаю неправильно?

P.S. Использование CreateSQLQuery необходимо, потому что мой дочерний объект foo создан на основе его родительской панели, но bar и foo имеют один и тот же идентификатор и используют таблицу на конкретный класс

+0

Это не выглядит нормальным для меня. На необработанном уровне SQL мы можем читать несанкционированные данные на любом уровне изоляции при условии, что мы читаем транзакцию с ожидающими данных. Проверяя 'ExecuteUpdate', он должен немедленно отправить запрос на db. Можете ли вы проверить это в своем случае с профилировщиком? Затем 'Get' должен найти ваш новый объект, если только вы не находитесь в каком-то конкретном случае, например, если в вашем сеансе есть устаревший объект с тем же идентификатором, но помечен для удаления. Включите протоколы log4net журнала NHibernate, а журналы из 'DefaultLoadEventListener' должны предоставить вам подробную информацию. –

+0

Нет, после ExecuteUpdate, профайлер говорит, что i ', просто отправьте Insert, но не зафиксируйте. Я думаю, что это зависит от стиля жизни ISessionProvider. –

+0

Просто отправка вставки была тем, что я ожидал увидеть в профилировщике. В любом случае, ваш комментарий [здесь] (/ questions/36386613/using-creationqlquery-with-insert-query-in-nhibernate? Noredirect = 1 # comment60434278_36388601) говорит, что вы что-то нашли, вероятно, вы должны добавить его в качестве ответа на свой собственный вопрос, и принять его. Или, если вы не понимаете, почему ваше изменение заставляет ваш код работать, может быть, вы должны задать новый вопрос. –

ответ

0

Я нашел решение.

В моем случае, ISessionProvider есть Стиль жизни - perWebRequest. Это означает, что сеанс должен быть выполнен после окончания веб-запроса.

Дальше. После вставки у нас нет объекта, но мы можем объединить новый объект, созданный на основе данных для вставки, с текущим сеансом.

session.Merge(new Entity(...)); 

или если у вас есть родительский объект в Persistence Context, вам нужно сделать так:

session.Evict(parentEntity); 
session.Merge(new Entity(...)); 

Evict удалить объект с некоторым идентификатором (ребенка и родителя есть идентификатор), иначе вы получите исключение. Это объединит сущность с текущим сеансом, а когда вы используете sessison.Get<MyObjectType>(entityId), объект не будет пустым.

0

Либо совершить первую транзакцию перед попыткой .Get, либо вы можете использовать .Load, если вам нужно связать этот объект с другим объектом перед обновлением или вставкой.

Написание сырых sql-запросов не будет сохранять вещи в сеансе, поскольку вы не имеете дело с сущностями.

+0

Я немного удивлен. Разве мы не можем читать данные, добавленные в текущей ожидающей транзакции, если мы читаем эту транзакцию? Обычно нам не нужно совершать транзакции. Выполняется ли 'ExecuteUpdate' только на' Flush'? (Если это был случай обновления SQL на уже загруженных объектах, нам нужно было бы выселять объекты из сеанса.) –

+0

Это зависит от уровня изоляции транзакции, который вы используете при чтении данных. Вам нужно было бы явно указать, чтобы он читал незафиксированные данные, чтобы это сделать, и предполагается, что обновление/вставка фактически отправлена ​​в базу данных в транзакции, которая все еще находится на рассмотрении. –

+0

Вы меня сомневаетесь, но тестирование в прочитанном означает «начать движение»; вставьте значения Parametre (Code) ('test'); выберите * из параметра; откатить; выберите * from parametre; 'дает меньше результата во втором случае, то есть нам не нужно читать незафиксированные для чтения ожидающих данных, если мы все еще находимся в одной транзакции. И в случае с вставкой, я не понимаю, почему NHibernate кэша первого уровня может помешать. –

Смежные вопросы