-->
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.  [ 12 posts ] 
Author Message
 Post subject: How to map properties with a type System.Type?
PostPosted: Tue Jul 10, 2007 1:17 pm 
Newbie

Joined: Sat Jul 07, 2007 8:46 pm
Posts: 6
I have a class:
Code:
public class Comment
    {
        #region private fields
        private int? id;
        private string text;
        private DateTime createdOn;
        private User createdBy;
        private object objectId;
        private Type objectType;
        #endregion

        #region public properties
        public Comment()
        {
            CreatedOn = DateTime.Now;
        }

        virtual public int? Id
        {
            get { return id; }
            set { id = value; }
        }

        virtual public string Text
        {
            get { return text; }
            set { text = value; }
        }

        virtual public DateTime CreatedOn
        {
            get { return createdOn; }
            set { createdOn = value; }
        }

        virtual public User CreatedBy
        {
            get { return createdBy; }
            set { createdBy = value; }
        }

        virtual public object ObjectId
        {
            get { return objectId; }
            set { objectId = value; }
        }

        virtual public Type ObjectType
        {
            get { return objectType; }
            set { objectType = value; }
        }
       
        #endregion
    }

Bascally a POCO object with a property typeof System.Type.

In my mapping file:
Code:
<property name="ObjectType" column="[ObjectType]" type="Type"/>


But I always get exception "Object reference not set to an instance of an object." when I tries to load a collection.

Have I done something wrong?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 11:10 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Need more info. Doesn't look like this property is the problem, though.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 3:03 pm 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi cloudster!

What would you store in DB for this "type" and what is more interesting - for objectId?
Are you really want to create association from this class to EVERY other possible persistent class? But then I believe you have to create some sort of common interface, or even common (abstract) base class for every other persistent class in whole application - to map ObjectId to this class/interface... And of course you have to use one common sequence of values for ids - uuid for example.

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 6:03 pm 
Newbie

Joined: Sat Jul 07, 2007 8:46 pm
Posts: 6
Hi Igork,

This is my way to solve the lack-of-mixin problem in C#. I am developing a web application.
I have interfaces like IFileAttachable, ICommentable, ITaggable.
All the interfaces have no member.

If the current object is ICommentable, my controller will automatically use ICommentService to load the comment from db. like this:
Code:
     public ICollection<Comment> GetComments(ICommentable obj)
        {
            Type objType = obj.GetType();

            return repository.FindAll(Where.Comment.ObjectId == obj.Id
                && Where.Comment.objectTypeString == objType.AssemblyQualifiedName
                && Where.Comment.AddOrder(OrderBy.Comment.CreatedOn.Asc)
            );
        }


Then a comment section will be rendered automatically if the current object is ICommentable.

So in db side, my comments table is not associated with any other classes. I have to load/save comments basing on the current object. Before, I have this work perfectly if I map the Type directly. I changed to nhibernate trunk version and now have to convert the Type to its AssemblyQualifiedName by myself. Something strange.


IgorK wrote:
Hi cloudster!

What would you store in DB for this "type" and what is more interesting - for objectId?
Are you really want to create association from this class to EVERY other possible persistent class? But then I believe you have to create some sort of common interface, or even common (abstract) base class for every other persistent class in whole application - to map ObjectId to this class/interface... And of course you have to use one common sequence of values for ids - uuid for example.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 6:08 pm 
Newbie

Joined: Sat Jul 07, 2007 8:46 pm
Posts: 6
Forget to say all classes in my model layer use int as identifier for the persistent purpose. So they do have a common interface.

IgorK wrote:
Hi cloudster!

What would you store in DB for this "type" and what is more interesting - for objectId?
Are you really want to create association from this class to EVERY other possible persistent class? But then I believe you have to create some sort of common interface, or even common (abstract) base class for every other persistent class in whole application - to map ObjectId to this class/interface... And of course you have to use one common sequence of values for ids - uuid for example.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 5:25 am 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi cloudster!

Then maybe you'd better map this field to string instead of Type?

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 1:20 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Igor,

See here: System.Type automatically maps to string (nvarchar) on the DB side. It works by saving the FQN of the type, I believe. But to load it, the same assembly needs to be available.

cloudster,

what is the full stack trace of the exception? If it is intermittent, it may be because NH is having difficulty loading a particular type. Maybe the comment was saved in one program for a type from a given assembly, then you tried to reload it in another program where that same assembly wasn't available? In that case, Igor may be right: you might be better off just storing the type FQN in a string on the object yourself. Less elegant, but maybe a necessary tradeoff.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 4:13 pm 
Newbie

Joined: Sat Jul 07, 2007 8:46 pm
Posts: 6
I am using a string field now as a workaround.
Code:
private string objectTypeString;
virtual public Type ObjectType
{
    get { return Type.GetType(objectTypeString); }
    set { objectTypeString = value.AssemblyQualifiedName; }
}

and
<property name="objectTypeString" access="field" column="[ObjectType]"/>

It works.

But I am using ayende's NHibernate Query Generator and I have to write code like

repository.FindAll(Where.Comment.ObjectId == obj.Id
&& Where.Comment.objectTypeString == objType.AssemblyQualifiedName
&& Where.Comment.AddOrder(OrderBy.Comment.CreatedOn.Asc));

I just hope I can compare the type directly, not the AssemblyQualifiedName.

Don't know why it's not working.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 5:42 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
What is the full stack trace of the exception?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 8:05 pm 
Newbie

Joined: Sat Jul 07, 2007 8:46 pm
Posts: 6
I found I can't use

return repository.FindAll(Expression.Eq("ObjectType", objType));

return repository.FindAll() is OK.

The Positional parameter is null which means the objType is not converted to string correctly.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 10:55 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
FindAll() is not familiar to me, is it yours? What is the code underlying it? Does this really throw an exception, or does it just not return any results?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 13, 2007 1:33 am 
Newbie

Joined: Sat Jul 07, 2007 8:46 pm
Posts: 6
FindAll() is just a wrapper of List<T>(). One exception is thrown from nhibernate.dll.

"Object reference not set to an instance of an object."

Looks I can't use Expression.Eq for system.Type.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 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.