NHibernate сохранит, но не загрузит объект - PullRequest
5 голосов
/ 02 февраля 2010

Я получаю очень странную ошибку с NHibernate 2.1.2.4000 GA и последней версией FluentNHibernate.Я могу сохранить объект, но не могу загрузить его обратно после вызова Flush () и Clear ().

Это мой объект:

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)

Я не уверен, стоит ли мне вызывать Flush () и Clear () (все ещеисследования), но я получаю эту ошибку при написании тестов с PersistenceSpecification.Вот как делает PersistenceSpecification в CheckList (), чтобы проверить, правильно ли сохраняется список, что не для меня.Я вошел в код и попал к этому репродукции.

Строка приложения правильно вставлена ​​в базу данных, но она больше не загружается.Это происходит как с SqlServer, так и с Sqlite.

Надеюсь, вы, ребята, можете мне помочь.

Спасибо большое!

Ответы [ 4 ]

2 голосов
/ 02 февраля 2010

Вы устанавливаете идентификатор, но это идентичность. Вы не должны устанавливать это, SQL делает это за вас.

Вместо создания нового сеанса используйте тот же и извлекайте его, используя Get вместо Load.

О разнице между Load и Get: http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx

1 голос
/ 08 февраля 2010

Я думаю, что вы забираете Id из myApp слишком рано. Попробуйте сделать _session.Flush(), прежде чем искать Id. Поскольку вы используете Identity Generator, NHibernate создает сгенерированный Id обратно на ваш объект, но этого не происходит до тех пор, пока сеанс не сбрасывается (обычно во время транзакции).

0 голосов
/ 07 февраля 2010

вам не нужно очищать вручную, так как фреймворк заметит, что вы выполняете поиск по объекту, в котором еще есть ожидающие изменения, эти изменения будут сброшены до получения, в этом я думаю, что idMyApp будет 1 вместо правильного сгенерированного идентификатора из базы данных .... вызывая сбой вашего кода получения ...

0 голосов
/ 03 февраля 2010

Вы используете два разных способа создания сессии?

NHibernateHelper.CreateSession();

и

_sessionFactory.OpenSession();

возможно, вам следует попробовать _sessionFactory.OpenSession (); получить сеанс для поиска.

...