Why does NHibernate say my filter isn't configured?
I'm trying to use a global filter in NHibernate, and as far as I can tell I'm doing exactly what all the tutorials do, but I'm getting an exception.
My .hbm.xml file contains the following:
...
<class name="NHibernateSandbox.Foo, NHibernateSandbox" table="Foo">
...
<property column="Content" type="String" name="Content" not-null="true" length="100" />
<property column="Deleted" type="Boolean" name="Deleted" not-null="true" />
<filter name="Foo_Nondeleted" condition="Deleted = false" />
</class>
Then I have a simple test class:
Configuration cfg = new Configuration();
cfg.Configure();
using (ISessionFactory sf = cfg.BuildSessionFactory()) {
using (ISession session = sf.OpenSession()) {
session.EnableFilter("Foo_Nondeleted");
IQuery query = session.CreateQuery("FROM NHibernateSandbox.Foo");
foreach (Foo foo in query.List<Foo>()) {
Console.WriteLine(foo.Content);
}
}
}
If I remove the EnableFilter
line it works as expected: both deleted and undeleted rows are printed. However, with the EnableFilter
line I get an NHibernateException
No such filter configured [Foo_Nondeleted]
at NHibernate.Impl.SessionFactoryImpl.GetFilterDefinition(String filterName)
a开发者_Python百科t NHibernate.Impl.SessionImpl.EnableFilter(String filterName)
at NHibernateSandbox.Program.Main(String[] args)
If I configure log4net to be verbose then I see
INFO NHibernate.Cfg.HbmBinder - Mapping class: NHibernateSandbox.Foo -> Foo
DEBUG NHibernate.Cfg.HbmBinder - Mapped property: Id -> RID, type: Int32
DEBUG NHibernate.Cfg.HbmBinder - Mapped property: Content -> Content, type: String
DEBUG NHibernate.Cfg.HbmBinder - Mapped property: Deleted -> Deleted, type: Boolean
DEBUG NHibernate.Cfg.HbmBinder - Applying filter [Foo_Nondeleted] as [Deleted = false]
What's the missing step between it "applying filter" and the filter being "configured" and available to the session?
It's not enough to add a filter to the class: you have to define it as well. This comes down to adding
<filter-def name="Foo_Nondeleted"></filter-def>
to the .hbm.xml file. Note that there's a catch here: although tutorials show it before the classes, it has to be placed after them in the XML or you'll get an XmlSchemaValidationException
.
There's another small change which needs to be made too: even though you might have query.substitutions
set up to map false
to 0
, it isn't applied to the filter condition, so you'll have to change the filter to
<filter name="Foo_Nondeleted" condition="Deleted = 0" />
精彩评论