Are there occasions when NHibernate won't return a proxy object?

百般思念 提交于 2020-02-04 02:57:47

问题


I'm learning Fluent NHibernate (and by extension, NHibernate generally). I'm using auto-mapping with some overrides, but I don't think that is important for the question (of course, if I'm wrong here I'll gladly update the question).

Given an ISession (and a few more assumed variables) I can return entities by their ID:

using (var session = SessionFactory.OpenSession())
{
    var user = session.Get<User>(userId);
}

My limited understanding was that NHibernate creates a proxy around the User mapped entity, yet when I test it (based on this):

Assert.That(user is INHibernateProxy, "Not a proxy.");

It appears as though my instance is not a proxy.

Are there occasions where proxies are not used? I'm hoping for the "missing piece" and praying this isn't the Friday afternoon brain-fail.


回答1:


Generally proxies are for lazy loading. Whenever you're fetching entitles by Get etc., you're not getting proxies, but the real objects. NHibernate don't use proxies when not necessary.

But if user has an Address, user.Address is INHibernateProxy will be true (unless lazy loading is turned off for this relationship).

For more info about how and when NHibernate handles proxies, see this article.




回答2:


ISession.Get always return either null or a real object. ISession.Load OTOH can return a proxy (or throw an exception), but proxying is a whole other story: your persistent classes should satisfy some preconditions (virtual properties, non-sealed, etc.).




回答3:


As NOtherDev stated, proxies are for lazy-loading. But even Session.Get sometime returns a proxy. This caught me off guard several times. If you use lazy loading for any column in the table by specifying lazy="true" like this:

<property name="Description" type="StringClob" not-null="false" lazy="true"/>

Session.Get will always return proxies for this type, and there is no way to unproxy the object. In fact, the proxy is the real object.

By the way, disabling lazy-loading is really, really a bad idea. You can read more about that here: NHibernate is lazy, just live with it




回答4:


Some questions are never too old ;) In real live, you usally get proxies by access "parent" of inverse relationship or by loading an object by Load(). But if the object has already been loaded in the cache before, you will get the type of the first access. So Load/Get might both return proxy or real instance.

        // if object has been loaded, load will return real instance
        using (var session = CreateSession())
        {
            postByGet = session.Get<Post>(post1Id);
            postByLoad = session.Load<Post>(post1Id);

            Assert.IsFalse(postByGet is INHibernateProxy);
            Assert.IsFalse(postByLoad is INHibernateProxy);
            Assert.IsTrue(object.ReferenceEquals(postByGet, postByLoad));
        }

        // if proxy has been loaded, get will return filled proxy
        using (var session = CreateSession())
        {
            postByLoad = session.Load<Post>(post1Id);
            postByGet = session.Get<Post>(post1Id);

            Assert.IsTrue(postByGet is INHibernateProxy);
            Assert.IsTrue(postByLoad is INHibernateProxy);
            Assert.IsTrue(object.ReferenceEquals(postByGet, postByLoad));
        }


来源:https://stackoverflow.com/questions/9843310/are-there-occasions-when-nhibernate-wont-return-a-proxy-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!