我在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上。
希望你们能帮帮我。
非常感谢!
答案 0 :(得分:2)
您正在设置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
答案 1 :(得分:1)
我认为你过早地从Id
中抓取myApp
。在查找_session.Flush()
之前,请尝试Id
。由于您使用的是Identity Generator,因此NHibernate会将生成的Id冒充回您的对象,但直到会话被刷新(通常在事务提交时)才会发生。
答案 2 :(得分:0)
您使用两种不同的方式来创建会话吗?
NHibernateHelper.CreateSession();
和
_sessionFactory.OpenSession();
也许你应该尝试sessionFactory.OpenSession();得到一个会议进行检索。
答案 3 :(得分:0)
您不需要手动刷新,因为框架会注意到您对仍有待更改的实体执行搜索,这些更改将在获取之前刷新,在此我认为idMyApp将为1而不是从数据库中生成的正确的id ....导致你的获取代码失败...