Unexpected proxy objects in Nhibernate with compos

2019-07-25 16:19发布

问题:

I have a data structure which uses composite ids (Which I dont wish to change to single) Everything loads fine except for many-to-one joins which if the join is empty, instead of mapping the property to null, maps it to an empty proxy object. I have written an ugly work around( see bleow). Any solutions to this?

private Node _Parent;

    public Node Parent
    {
        get
        {
            return this._Parent;
        }
        set
        {
            this._Parent = Proxy.Check<Node>(value);
        }
    }
internal static class Proxy
{
    public static T Check<T>(T obj) where T : PersistentObject
    {
        if (obj is NHibernate.Proxy.INHibernateProxy && obj != null)
        {
            try 
            {
                int id = obj.ID;
                return obj;             
            }
            catch //Proxy only object cant retrieve ID
            {
                return null;
            }
        }
        else
        {
            return obj;
        }
    }

}

with the mapping file beginning

<class name="Node" table="Node">
    <composite-id>
        <key-property name="ID"/>
        <key-property name="VersionID"/>
    </composite-id>

and accessed by

    <many-to-one name="Node" class="Node" >
        <column name="NodeID"/>
        <column name="VersionID" />
    </many-to-one>

回答1:

Not exactly sure if this is the perfect fix for this situation, but this fixed the issue for me when I encountered the same problem while working on an old DB with composite keys.

By setting not-found to ignore on your links, NHibernate will treat empty objects as null instead of exceptions. When using this technique NHibernate will execute a seperate query so there may be small performance hits, as this is basically eager loading the object.

You could try just eager loading the object instead of using this technique, but I have a feeling it would return an exception as it would be expecting an object (not null). I would suggest posting a question in the NHibernate forums if this doesn't work as I am definately not an expert in this area, but this may be a smaller/less ugly work around for you.

For example:

<many-to-one name="Node" class="Node" not-found="ignore">
    <column name="NodeID"/>
    <column name="VersionID" />
</many-to-one>

Hope this helps,

Jay