我在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()断言上的作用,以验证列表是否正确保存,这不适合我 . 我进入了代码,并得到了这个repro .
应用程序行已正确插入数据库中,但不会再次加载 . 它发生在SqlServer和Sqlite上 .
希望你们能帮助我 .
非常感谢!
4 回答
您正在设置ID,但它是一个身份 . 你不应该设置它,SQL会为你做这件事 .
而不是创建新会话使用相同的会话,并使用Get而不是Load进行检索 .
关于Load和Get之间的区别:http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx
我认为你过早地 grab 了
myApp
. 在查找Id
之前尝试做_session.Flush()
. 因为直到会话被刷新(通常在事务提交时),才会发生 .您使用两种不同的方式来创建会话?
和
也许你应该尝试_sessionFactory.OpenSession();得到一个检索会话 .
您不需要手动刷新,因为框架会注意到您对仍有待更改的实体执行搜索,这些更改将在get之前刷新,在此我认为idMyApp将为1而不是正确生成了数据库中的id ....导致你的获取代码失败......