These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Abstract base class as class proxy...
PostPosted: Sun Aug 06, 2006 11:37 pm 
Beginner
Beginner

Joined: Thu Dec 08, 2005 6:49 pm
Posts: 49
Why is specifying an abstract base class as the proxy for a persistent class not allowed?

Code:
MappingException: proxy must be either an interface, or the class itself

Would this cause undesirable side-effects of some description?

Since the constructor of my persistent class does a lot of initialization that is redundant for a proxy instance, I want to split it into two classes.
1. A minimal abstract one.
2. A concrete one with all the important initialization in the constructor.

I understand that specifying an inteface is the usual way to achieve this, but as my following example should illustrate, I need to prefetch certain properties so they can be read without causing initialization.
That is, I need to control which members are virtual and ensure that "hibernate.use_proxy_validator" is set to false.

I would really prefer not to have to contaminate my domain layer with calls to !NHibernateUtil.IsInitialized(this) in all the constructors.

Code:
interface IBlogItem
{
    DateTime ItemDate { get; set; }
    string Text { get; set; }
}

abstract class AbstractBlogItem : IBlogItem
{
    private DateTime _itemDate;
    private string _text;

    //will NOT cause initialization
    public DateTime ItemDate
    {
        get { return _itemDate; }
        set { SetItemDate(value); }
    }

    //will cause initialization
    public virtual void SetItemDate(DateTime name)
    {
        _itemDate = name;
    }

    //will cause initialization
    public virtual string Text
    {
        get { return _text; }
        set { _text = value; }
    }
}

class BlogItem : AbstractBlogItem
{
    public BlogItem()
    {
        //intenstive initialization that is
        //not relevant to a proxied instance
    }
}

static class Program
{
    static void Main()
    {
        using (ISession session = _factory.OpenSession())
        {
            IList<object[]> rows = session.CreateQuery(
                "select b.ItemDate " +
                "from BlogItem b").List<object[]>();
            IList<IBlogItem> blogItems = new List<IBlogItem>(rows.Count);

            foreach (object[] row in rows)
            {
                AbstractBlogItem blogItem =
                    session.Load<AbstractBlogItem>(row[0]);
                typeof (AbstractBlogItem).GetField("_itemDate",
                    BindingFlags.Instance | BindingFlags.NonPublic)
                    .SetValue(blogItem, row[0]);
                blogItems.Add(blogItem);
            }
        }
    }
}


Cheers.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 07, 2006 12:01 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I can't think of any ill effects right now. Try just disabling the relevant check and see what happens. I don't know of any other workaround for your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 09, 2006 9:03 am 
Beginner
Beginner

Joined: Thu Dec 08, 2005 6:49 pm
Posts: 49
sergey wrote:
I don't know of any other workaround for your problem.


Rather than playing around with the source, I have added the following property to the base class that all my domain objects inherit from:

Code:
protected bool IsNotProxy
{
    get
    {
        Type type = GetType();
        return (type.Module == type.BaseType.Module);
    }
}

I then conditionally initialize all my objects with the following constructor condition (reminds me a little of the Form.DesignMode property):

Code:
public class Blog : BaseDomainObject
{
    public Blog()
    {
        if (IsNotProxy)
        {
            //initialize
        }
    }
}


Given that proxy objects will always reside in a dynamic module, I figure this is a good generic way to detect them. If anybody can suggest a more efficient/robust method then I'm all ears.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.