开发者

NHibernate - why is this static method legal in this domain class?

I have read in Chapter 4 of the NHibernate docs that all of a persistent classes public methods, properties and events must be declared as virtual.

However, whilst a runtime error is generated for any Properties that are not marked as virtual, I have found that static methods are allowed and do not generate a runtime error . As they are static they are of course not marked virtual which seems to break the rule in point 4.1.4 of the documentation (see above). I have checked the resulting sql and it also implements lazy loading correctly when I run a test against the method so is it therefore ok to use static methods?

Here's the basic details of the persistant class:

public class CmsPage
{
    public virtual int? Id { get; set; }
    public virtual string Title { get; set; }

    public virtual void Update()
    {
        using (ISession session = NHibernateHelper.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Update(this);
                transaction.Commit();
            }
        }
    }

    // Note: static and non-virtual and yet it will not cause a problem for Nhibernate
    public static IEnumerable<CmsPage> GetList()
    {
        IList<CmsPage> pa开发者_如何学编程geList;
        using (ISession session = NHibernateHelper.OpenSession())
        {
            string hql = "from CmsPage p";
            pageList = session.CreateQuery(hql)
                .List<CmsPage>();
        }

        return pageList;
    }
}

So my question is why is it ok to use a static method in the persistent domain class when the documentation seems to say it's not?

Please answer from NHibernate's point of view not an OO design point of view; I don't want to get into an OOD/OOP debate if it can be avoided please.


The documentation says: "NHibernate works best if these classes follow some simple rules, ..." It doesn't say it won't work (clearly it does work).

So, really, the discussion boils down to an OO issue.


Actually this applies only to properties. Methods are not persisted, so proxies and lazy-loading does not apply. Ideally you should separate data access (the static methods in your case) from the domain object. But you are correct to point this out, maybe the documentation should have been clearer.

In conclusion your class is perfectly fine but it could be even better if you separated the concerns.


NHibernate needs all your properties to be virtual because it carries out its lazy-loading magic by making proxies of your objects that override everything. So when you write this code:

class Foo {
    public virtual Foo[] Neighbors { get; set; }
}

NHibernate secretly generates classes like:

class NHProxy03450843275 : Foo {
    public virtual Foo[] Neighbors { /* Godawful lazy-loading magic goes here */ }
}

Actually it's worse than that, but this gives you the idea. Anyway, static methods aren't bound to particular instances of a class, so NH doesn't need proxies to deal with them. Thus they can be non-virtual.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜