Я получаю очень странную ошибку с NHibernate 2.1.2.4000 GA и последняя версия FluentNHibernate. Я могу сохранить объект, но не могу загрузить его назад после вызова для Сбрасывания () и Ясный ().
Это - мой объект:
public class Application { public int Id { get; set; } public string Name { get; set; } public string KeyName { get; set; } public string Description { get; set; } public string Url { get; set; } public override bool Equals(object obj) { if (null != obj && obj is Application) { return ((Application)obj).Id == this.Id; } else { return base.Equals(obj); } } }
Моя Карта конфигурации:
public class ApplicationMap : ClassMap { public ApplicationMap() { Table("[Application]"); Not.LazyLoad(); Id(x => x.Id, "ApplicationId") .GeneratedBy.Identity(); Map(x => x.Name, "ApplicationName") .Nullable() .Length(50); Map(x => x.Description, "ApplicationDescription") .Nullable() .Length(200); Map(x => x.KeyName, "ApplicationKeyName") .Nullable() .Length(50); Map(x => x.Url, "ApplicationLink") .Nullable() .Length(50); } }
Как я создаю свой ISession:
var _sessionFactory = Fluently.Configure() .Database( SQLiteConfiguration.Standard.InMemory() .ProxyFactoryFactory(typeof(ProxyFactoryFactory))) .Mappings( m => m.FluentMappings.AddFromAssemblyOf()) .ExposeConfiguration(cfg => Config = cfg) .BuildSessionFactory(); var _session = _sessionFactory.OpenSession();
И это - код, который не будет работать:
Application myApp = new Application() { Id = 1, Description = "MyApp", KeyName = "MyApp", Name = "My App", Url = "http://www.myapp.com" }; _session.Save(myApp); var idMyApp = myApp.Id; _session.Flush(); _session.Clear(); _session = NHibernateHelper.CreateSession(); var a = _session.Load(idMyApp);
Исключение, которое я получаю в данный момент, я пытаюсь Загрузиться, объект назад от базы данных:
Test method HNI.Portal.Test.MappingTests.RoleMap.CanCorrectMapRole threw exception: NHibernate.ObjectNotFoundException: No row with the given identifier exists[HNI.Portal.Core.Entities.Application#1].
и StackTrace:
NHibernate.Impl.SessionFactoryImpl.DefaultEntityNotFoundDelegate.HandleEntityNotFound(String entityName, Object id) NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType) NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType) NHibernate.Impl.SessionImpl.Load(String entityName, Object id) NHibernate.Impl.SessionImpl.Load(Type entityClass, Object id) NHibernate.Impl.SessionImpl.Load[T](Object id)
Я не уверен, должен ли я назвать Сброс () и Ясный () (все еще проводящий исследование в области его), но я получаю эту ошибку при записи тестов с PersistenceSpecification. Это - то, как PersistenceSpecification делает на CheckList (), утверждают, чтобы проверить, сохраняется ли список правильно, который не является для меня. Я ступил в код и добрался до этой репродукции.
Строка приложения правильно вставляется в базу данных, но она не загрузится снова. Это происходит и с SqlServer и с Sqlite.
Надеюсь Вы, парни могут помочь мне.
Большое спасибо!
Вы используете два различных способа создания сессии?
NHibernateHelper.CreateSession();
и
_sessionFactory.OpenSession();
может быть, Вам следует попробовать _sessionFactory.OpenSession(); чтобы получить сессию для извлечения.
Вы устанавливаете идентификатор, но это идентификатор. Вы не должны устанавливать его, SQL сделает это за вас.
Вместо создания нового сеанса используйте тот же самый и для получения используйте Get вместо Load.
О разнице между загрузкой и получением: http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load -and-querying-by.aspx
вам не нужно смывать вручную, так как фреймворк заметит, что вы выполняете поиск в сущности, изменения в которой еще ожидают, эти изменения будут смыты до получения, в этом я думаю, что idMyApp будет 1, а не правильно сгенерированный id из базы данных...., так как ваш код get to fail...
Я думаю, вы схватили Id
из myApp
слишком рано. Попробуйте выполнить _session.Flush ()
, прежде чем искать Id
. Поскольку вы используете генератор идентификаторов, NHibernate переносит сгенерированный идентификатор обратно в ваш объект, но этого не происходит до тех пор, пока сеанс не будет сброшен (обычно во время фиксации транзакции).