nHibernate不会检索手动更改的数据

时间:2008-09-24 22:30:55

标签: nhibernate

nHibernate无法从存储库表中检索手动更改的数据?我也禁用了二级缓存,但看起来它(nhibernate)有时从缓存中检索,有时从存储库表中检索。

7 个答案:

答案 0 :(得分:6)

nhibernate中有两种类型的缓存:会话缓存和二级缓存。会话缓存始终缓存该会话看到的对象 - 这是nhibernate如何知道哪些对象已更改并需要持久化。您禁用的二级缓存低于该缓存。您看到缓存的信息来自会话缓存。

如果您的应用程序需要查看其他来源(例如,手动数据库更改)持续存在的更改,则答案可能是以更精细的粒度创建会话。虽然SessionFactory在应用程序的生命周期中存在,但应该更频繁地创建Session对象。例如,在Web应用程序中,每个请求都会生成自己的会话。

如果那不是一个选项,session.Clear()将驱逐会话中的所有对象。

答案 1 :(得分:2)

与NHibernate的良好关系始终取决于强大的OO承诺,并且在大多数常见情况下取决于数据变更的排他性。如果你没有它,你会看到一些令人讨厌的问题,并且会放弃NH提供的大部分非常好的东西。

假设有一个名为“Foo”的类映射到表“Foo”,其列为“Id”和“SomeProperty”。如果所有行都将“SomeProperty”从“oldValue”手动更新为“newValue”,并且NH向DB发送一些查询,询问SomeProperty =“newValue”的所有Foos,则DB将按预期返回所有Foos。但是,Foo实例NH传递可能具有“oldValue”,因为返回Id的Foo已经附加到会话中(换句话说,它是在第一级缓存上)。

使NHibernate知道所有手动更新的唯一简短方法是使用StatelessSesion,因此它不会缓存对象实例并始终提供数据库版本的数据。但是,如果你想在交易系统上应用它,这是一个明显的标志,即不适当使用NH,你将无法获得大部分不错的NH功能。

答案 2 :(得分:1)

我不知道它是否会解决您遇到的问题,但文档说明:

  

要从会话缓存中完全逐出所有对象,请调用ISession.Clear()

     

对于二级缓存,在ISessionFactory上定义了一些方法,用于驱逐实例,整个类,集合实例或整个集合角色的缓存状态。

如果您每次执行此操作时都会对可能在带外更改的数据执行SELECT,则应该执行您想要的操作。

答案 3 :(得分:0)

我认为你必须更准确地描述你的确切问题才能得到答案;我对nhibernate有一些最小的经验,但我不能真正复制正在发生的事情,并尝试修复它,而不是说一些代码。

答案 4 :(得分:0)

因为过于具体而反对

Nhibernate正在检索数据而没有任何问题。 但是当我手动更改存储库表中的数据时。 Icriterea(nhibernate)有时会从缓存或表中获取。 我正在使用Icriteria funcnality:

ICriteria criteria = session.CreateCriteria(typeof(xyzclass));                 criteria.Add(Expression.Eq(“xyzclass”,somestringto retreivedata));                 criteria.SetCacheable(假);                 return criteria.UniqueResult();

答案 5 :(得分:0)

我从来没有真正使用过NHibernate的缓存功能,但我相信它的目的是根本不需要去数据库,这意味着它不会进行手动更改,因为它不会知道他们。

我确切地问你在这里想要实现的是什么,你只是通过手动编辑数据库进行一些测试,还是在实时应用程序中进行常规活动?实际上,应该修改数据库的唯一事情是应用程序,通过NHibernate数据层执行此操作,以便在此过程中更新和/或弄脏缓存。

答案 6 :(得分:0)

这只是测试的一部分。

但是将来我们可以手动编辑数据表。 我还为该表设置了lazy为false,并注释掉了hibernate使用的所有二级缓存属性。 但即使这样,它也会返回不同的值而不是新编辑的值。 有时它给了我旧的价值,有时是新的,所以它不是一成不变的。