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: Problems calling nhibernate methods via reflection
PostPosted: Thu Sep 21, 2006 5:25 am 
Newbie

Joined: Thu Sep 21, 2006 5:08 am
Posts: 5
Location: Devon, England
Hibernate version:1.0.2.0

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" assembly="TMSEntities" namespace="TMS.CAP.Entities">
<class name="CallCentre" table="CallCentre">

<id name="Id" column="ID" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<version column="hibernateversion" type="Int32" name="Hibernateversion" />
<bag name="RaisedByCallCentreIDApplicationList" inverse="true" lazy="true" >
<key column="RaisedByCallCentreID" />
<one-to-many class="Application" />
</bag>
<bag name="CallCentreIDSupportTicketList" inverse="true" lazy="true" >
<key column="CallCentreID" />
<one-to-many class="SupportTicket" />
</bag>
<property column="Description" type="String" name="Description" not-null="true" length="64" />
<property column="CreatedDate" type="DateTime" name="CreatedDate" />
<property column="CreatedBy" type="Guid" name="CreatedBy" />
<property column="UpdatedDate" type="DateTime" name="UpdatedDate" />
<property column="UpdatedBy" type="Guid" name="UpdatedBy" />
<property column="Active" type="Boolean" name="Active" not-null="true" />

</class>
</hibernate-mapping>


Hi, I am trying to retrieve a list of CallCentre classes (as described in the mapping file above) from my SQL server 2005 db. Normally this works fine, if for example I do the following:

Code:
CallCentreDataAccess a = new CallCentreDataAccess();
List<CallCentre> b = a.LoadCallCentreList();


However I am trying to create an instance of CallCentreDataAccess using reflection, and to invoke the LoadCallCentreList() method dynamically. The method is invoked ok, but throws an exception from within the NHibernate code. the exception is as follows:

Exception: {"Exception has been thrown by the target of an invocation."}
Inner Exception: {"in expected: <end-of-text> (possibly an invalid or unmapped class name was used in the query) [ from CallCentre order by Description]"}

The code to execute the method by reflection is as follows:

Code:
// get the type
Type theType = dataAccess.GetType("TMS.CAP.DataAccess.CallCentreDataAccess");

// create an instance
ConstructorInfo con = theType.GetConstructor(Type.EmptyTypes);
object instance = con.Invoke(new object[] { });
       
// Now call the method
MethodInfo loadListMethod = theType.GetMethod("LoadCallCentreList");     
object o = new object();
o = loadListMethod.Invoke(instance, null);


I have stepped through the hibernate source to the line responsible, and compared it against a call to this method that works. It appears that the name of the entity I am retrieving loses the full assembly and namespace names in the reflected version, i.e.

Non reflected version: Assembly.Namespace.CallCentre
Using refleciton: CallCentre

This is the only difference I could see... If anyone could provide me with any suggestions as how to correct this issue I would be very grateful!

Cheers.[/code]


Top
 Profile  
 
 Post subject: Re: Problems calling nhibernate methods via reflection
PostPosted: Thu Sep 21, 2006 6:52 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
leec wrote:
Code:
// get the type
Type theType = dataAccess.GetType("TMS.CAP.DataAccess.CallCentreDataAccess");

// create an instance
ConstructorInfo con = theType.GetConstructor(Type.EmptyTypes);
object instance = con.Invoke(new object[] { });
       
// Now call the method
MethodInfo loadListMethod = theType.GetMethod("LoadCallCentreList");     
object o = new object();
o = loadListMethod.Invoke(instance, null);


I have stepped through the hibernate source to the line responsible, and compared it against a call to this method that works. It appears that the name of the entity I am retrieving loses the full assembly and namespace names in the reflected version, i.e.

Non reflected version: Assembly.Namespace.CallCentre
Using refleciton: CallCentre

This is the only difference I could see... If anyone could provide me with any suggestions as how to correct this issue I would be very grateful!


AFAIK, when executing method, the code should behave no differently wether it was called via reflection or not...

So, are You sure that the dataAccess.GetType returns correct one? Not a old one from some other (old version of) assembly?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Hi
PostPosted: Thu Sep 21, 2006 7:03 am 
Newbie

Joined: Thu Sep 21, 2006 5:08 am
Posts: 5
Location: Devon, England
Thanks for the reply. I have checked the code by stepping into it and it does seem to be coming back with the correct type. If I do a QuickWatch on it then it shows up as Assemblyname.Namespace.CallCentreDataAccess, so it looks to be the right type. Also I deleted all old versions of the assembly, and rebuilt them and still the same.


Top
 Profile  
 
 Post subject: Re: Hi
PostPosted: Thu Sep 21, 2006 8:06 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
leec wrote:
Thanks for the reply. I have checked the code by stepping into it and it does seem to be coming back with the correct type. If I do a QuickWatch on it then it shows up as Assemblyname.Namespace.CallCentreDataAccess, so it looks to be the right type. Also I deleted all old versions of the assembly, and rebuilt them and still the same.


Have You verified that the session and sessionfactory are correctly set up in case of reflection call?

And, is there any inter-appdomain communication in case of reflection?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Hi!
PostPosted: Wed Sep 27, 2006 5:10 am 
Newbie

Joined: Thu Sep 21, 2006 5:08 am
Posts: 5
Location: Devon, England
Sorry this has taken so long for me to reply, I have been away for a few days....

I am not sure what you mean by setting up the "session and sessionfactory are correctly set up in case of reflection call" .... is there somethng specific I need to configure?

In case this is of any use, here are two stack traces...

1st from where it doesn't work (using reflection to create data access objects)

NHibernate.DLL!NHibernate.Hql.FromParser.Token(string token = "CallCentre", NHibernate.Hql.QueryTranslator q = { from CallCentre order by Description}) Line 39 C#
NHibernate.DLL!NHibernate.Hql.ClauseParser.Token(string token = "CallCentre", NHibernate.Hql.QueryTranslator q = { from CallCentre order by Description}) Line 103 + 0x1b bytes C#
NHibernate.DLL!NHibernate.Hql.PreprocessingParser.Token(string token = "order", NHibernate.Hql.QueryTranslator q = { from CallCentre order by Description}) Line 146 + 0x26 bytes C#
NHibernate.DLL!NHibernate.Hql.ParserHelper.Parse(NHibernate.Hql.IParser p = {NHibernate.Hql.PreprocessingParser}, string text = " from CallCentre order by Description", string seperators = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\", NHibernate.Hql.QueryTranslator q = { from CallCentre order by Description}) Line 32 + 0xf bytes C#

NHibernate.DLL!NHibernate.Hql.QueryTranslator.Compile() Line 127 + 0x34 bytes C#
NHibernate.DLL!NHibernate.Hql.QueryTranslator.Compile(NHibernate.Engine.ISessionFactoryImplementor factory = {NHibernate.Impl.SessionFactoryImpl}, System.Collections.IDictionary replacements = Count = 0x00000000, bool scalar = false) Line 115 + 0x7 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionFactoryImpl.GetQuery(string queryString = " from CallCentre order by Description", bool shallow = false) Line 443 + 0x27 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.GetQueries(string query = " from CallCentre order by Description", bool scalar = false) Line 1773 + 0x14 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.Find(string query = " from CallCentre order by Description", NHibernate.Engine.QueryParameters parameters = {NHibernate.Engine.QueryParameters}) Line 1735 + 0xd bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.Find(string query = " from CallCentre order by Description", object[] values = {Dimensions:[0x00000000]}, NHibernate.Type.IType[] types = {Dimensions:[0x00000000]}) Line 1720 + 0x23 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.Find(string query = " from CallCentre order by Description") Line 1710 + 0x15 bytes C#
DataAccess.dll!TMS.CAP.DataAccess.CallCentreDataAccess.LoadCallCentreList() Line 58 + 0x11 bytes C#
[External Code]
App_Web_dmewjwcy.dll!SystemMaintenanceTypeList.LoadObjectData() Line 93 + 0xe bytes C#
App_Web_dmewjwcy.dll!SystemMaintenanceTypeList.Page_Load(object sender = {ASP.systemmaintenancetypelist_aspx}, System.EventArgs e = {System.EventArgs}) Line 36 + 0x7 bytes C#
[External Code]



2nd where it does work, just by creating the data access objects manually in code:


NHibernate.DLL!NHibernate.Hql.FromParser.Token(string token = "TMS.CAP.Entities.CallCentre", NHibernate.Hql.QueryTranslator q = { from TMS.CAP.Entities.CallCentre order by Description}) Line 39 C#
NHibernate.DLL!NHibernate.Hql.ClauseParser.Token(string token = "TMS.CAP.Entities.CallCentre", NHibernate.Hql.QueryTranslator q = { from TMS.CAP.Entities.CallCentre order by Description}) Line 103 + 0x1b bytes C#
NHibernate.DLL!NHibernate.Hql.PreprocessingParser.Token(string token = "order", NHibernate.Hql.QueryTranslator q = { from TMS.CAP.Entities.CallCentre order by Description}) Line 146 + 0x26 bytes C#
NHibernate.DLL!NHibernate.Hql.ParserHelper.Parse(NHibernate.Hql.IParser p = {NHibernate.Hql.PreprocessingParser}, string text = " from TMS.CAP.Entities.CallCentre order by Description", string seperators = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\", NHibernate.Hql.QueryTranslator q = { from TMS.CAP.Entities.CallCentre order by Description}) Line 32 + 0xf bytes C#

NHibernate.DLL!NHibernate.Hql.QueryTranslator.Compile() Line 127 + 0x34 bytes C#
NHibernate.DLL!NHibernate.Hql.QueryTranslator.Compile(NHibernate.Engine.ISessionFactoryImplementor factory = {NHibernate.Impl.SessionFactoryImpl}, System.Collections.IDictionary replacements = Count = 0x00000000, bool scalar = false) Line 115 + 0x7 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionFactoryImpl.GetQuery(string queryString = " from CallCentre order by Description", bool shallow = false) Line 443 + 0x27 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.GetQueries(string query = " from CallCentre order by Description", bool scalar = false) Line 1773 + 0x14 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.Find(string query = " from CallCentre order by Description", NHibernate.Engine.QueryParameters parameters = {NHibernate.Engine.QueryParameters}) Line 1735 + 0xd bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.Find(string query = " from CallCentre order by Description", object[] values = {Dimensions:[0x00000000]}, NHibernate.Type.IType[] types = {Dimensions:[0x00000000]}) Line 1720 + 0x23 bytes C#
NHibernate.DLL!NHibernate.Impl.SessionImpl.Find(string query = " from CallCentre order by Description") Line 1710 + 0x15 bytes C#
DataAccess.DLL!TMS.CAP.DataAccess.CallCentreDataAccess.LoadCallCentreList() Line 58 + 0x11 bytes C#
App_Web_p0lhukc8.dll!SystemMaintenanceTypeList.LoadObjectData() Line 68 + 0xa bytes C#
App_Web_p0lhukc8.dll!SystemMaintenanceTypeList.Page_Load(object sender = {ASP.systemmaintenancetypelist_aspx}, System.EventArgs e = {System.EventArgs}) Line 36 + 0x7 bytes C#
[External Code]


Thanks again...


Top
 Profile  
 
 Post subject: Re: Hi!
PostPosted: Wed Sep 27, 2006 5:44 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
leec wrote:
I am not sure what you mean by setting up the "session and sessionfactory are correctly set up in case of reflection call" .... is there somethng specific I need to configure?


I did mean, is the usual Sessionfactory configuration done correclty? Are all assemblies/mappings etc added to sessionfactory as expected?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: yup
PostPosted: Wed Sep 27, 2006 5:53 am 
Newbie

Joined: Thu Sep 21, 2006 5:08 am
Posts: 5
Location: Devon, England
Yeah, everything else is ok. The mappings work ok in all other areas of the system. It is only when I create am object through reflection that I have a problem. If I just declare the objects in code and load/update/save them it all works fine.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 27, 2006 6:02 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
leec,

Could you try this two scenarios? The first one call reflection on Method invocation but not on object instantiation. The second one gets the other way round.

1.
Code:
// get the type
Type theType = dataAccess.GetType("TMS.CAP.DataAccess.CallCentreDataAccess");

// create an instance
object instance = new TMS.CAP.DataAccess.CallCentreDataAccess();

// Now call the method
MethodInfo loadListMethod = theType.GetMethod("LoadCallCentreList");     
object o = new object();
o = loadListMethod.Invoke(instance, null);


2.
Code:
// get the type
Type theType = dataAccess.GetType("TMS.CAP.DataAccess.CallCentreDataAccess");

// create an instance
ConstructorInfo con = theType.GetConstructor(Type.EmptyTypes);
object instance = con.Invoke(new object[] { });

// Now call the method
object o = ((TMS.CAP.DataAccess.CallCentreDataAccess)instance).LoadCallCentreList();


Top
 Profile  
 
 Post subject: Re: yup
PostPosted: Wed Sep 27, 2006 6:08 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
leec wrote:
Yeah, everything else is ok. The mappings work ok in all other areas of the system. It is only when I create am object through reflection that I have a problem. If I just declare the objects in code and load/update/save them it all works fine.

I did mean, is the callcontext correct in case of reflection? Is it using the same sessionfactory/session as rest of the code?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Tests
PostPosted: Wed Sep 27, 2006 6:19 am 
Newbie

Joined: Thu Sep 21, 2006 5:08 am
Posts: 5
Location: Devon, England
Ok, I think i tried this before, but I have just done it again.... With method 1 I get an exception saying "Object does not match traget type". The stack trace of method 1 is as follows:

" at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)\r\n at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)\r\n at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\r\n at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)\r\n at SystemMaintenanceTypeList.LoadObjectData() in c:\\Clients\\TMS\\TMSConsole\\SystemMaintenanceTypeList.aspx.cs:line 95\r\n at SystemMaintenanceTypeList.Page_Load(Object sender, EventArgs e) in c:\\Clients\\TMS\\TMSConsole\\SystemMaintenanceTypeList.aspx.cs:line 36\r\n at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)\r\n at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)\r\n at System.Web.UI.Control.OnLoad(EventArgs e)\r\n at System.Web.UI.Control.LoadRecursive()\r\n at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)"

With method 2 I get an exception saying "Unable to cast object of type 'TMS.CAP.DataAccess.CallCentreDataAccess' to type 'TMS.CAP.DataAccess.CallCentreDataAccess'" Which is a bit odd....

The stack trace for method 2 is:

" at SystemMaintenanceTypeList.LoadObjectData() in c:\\Clients\\TMS\\TMSConsole\\SystemMaintenanceTypeList.aspx.cs:line 97\r\n at SystemMaintenanceTypeList.Page_Load(Object sender, EventArgs e) in c:\\Clients\\TMS\\TMSConsole\\SystemMaintenanceTypeList.aspx.cs:line 36\r\n at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)\r\n at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)\r\n at System.Web.UI.Control.OnLoad(EventArgs e)\r\n at System.Web.UI.Control.LoadRecursive()\r\n at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)"


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 29, 2006 5:37 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
In Method 1
Code:
// get the type
Type theType = dataAccess.GetType("TMS.CAP.DataAccess.CallCentreDataAccess");

// create an instance
object instance = new TMS.CAP.DataAccess.CallCentreDataAccess();

// Now call the method
MethodInfo loadListMethod = theType.GetMethod("LoadCallCentreList");     
object o = new object();
o = loadListMethod.Invoke(instance, null);


I assume the variable "dataAccess" is a System.Reflection.Assembly instance.

Are you referencing two different versions of assembly named "TMS.CAP.DataAccess"?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 29, 2006 5:39 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Please check it out
Code:
Type type1 = dataAccess.GetType("TMS.CAP.DataAccess.CallCentreDataAccess");
Type type2 = typeof(TMS.CAP.DataAccess.CallCentreDataAccess);

bool shouldBeTrue = type1.Equals(type2);


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.