开发者

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" />
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜