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.  [ 14 posts ] 
Author Message
 Post subject: NHibernate 1.2 and Named Queries
PostPosted: Sun Dec 03, 2006 9:06 am 
Beginner
Beginner

Joined: Tue Nov 28, 2006 4:26 pm
Posts: 32
Location: Montreal, Quebec, Canada
I am trying to port some code that I had running fine under NHibernate 1.0.3 to now run under NHibernate 1.2 Beta 2. I managed to figure out some other differences between these versions. However, this one has me puzzled. I am not able to figure out why it would not be able to find named queries that were working in a previous version. Any ideas? I have included some more details to help diagnose. Thanks.

Hibernate version: 1.2 Beta 2

Mapping documents:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NHibernateProvider"
                   namespace="NHibernateProvider.Entity">
    <class name="Application" proxy="false">
        <!-- Primary key is auto-generated by the database's native method. -->
        <id name="Id">
            <generator class="native">
                <!-- Used for Oracle tests, does not affect MS SQL. -->
                <param name="sequence">Application_Id_SEQ</param>
            </generator>
        </id>
        <property name="Name" />
        <property name="LoweredName" />
        <property name="Description" />
    </class>
    <query name="Application.ByLoweredName">
        <![CDATA[
             from Application as app
            where app.LoweredName = ?
        ]]>
    </query>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
public static IList FindByNamedQuery(string queryName, object[] values, IType[] types)
{
    IList results;

    ISession session = GetCurrentSession();
    try
    {
        IQuery query = session.GetNamedQuery(queryName);
        if ((null != values) && (null != types))
        {
            for (int i = 0; i < values.Length; i++)
            {
                query.SetParameter(i, values[i], types[i]);
            }
        }
        results = query.List();
    }
    finally
    {
        CloseSession();
    }

    return results;
}


Full stack trace of any exception that occurs:
Code:
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: NHibernateProvider: unable to get application; operation failed with error "Named query not known: Application.ByLoweredName".

Base Exception Message: "Named query not known: Application.ByLoweredName"

Base Exception Stack Trace:    at NHibernate.Impl.SessionImpl.GetNamedQuery(String queryName) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Impl\SessionImpl.cs:line 2181
  at NHibernateProvider.Helper.NHibernateHelper.FindByNamedQuery(String queryName, Object[] values, IType[] types) in D:\Projects\Src\NHibernateProvider\NHibernateProvider\Helper\NHibernateHelper.cs:line 267
  at NHibernateProvider.Helper.NHibernateHelper.FindByNamedQuery(String queryName, Object value, IType type) in D:\Projects\Src\NHibernateProvider\NHibernateProvider\Helper\NHibernateHelper.cs:line 258
  at NHibernateProvider.Helper.NHibernateProviderEntityHelper.GetApplication(String appName) in D:\Projects\Src\NHibernateProvider\NHibernateProvider\Helper\NHibernateProviderEntityHelper.cs:line 83

Source Error:


Line 20:                 <add
Line 21:                   name="NHibernateProvider"
Line 22:                   type="NHibernateProvider.NHibernateRoleProvider"
Line 23:                   applicationName="NHibernateProviderTest" />
Line 24:             </providers>


Name and version of the database you are using: MS SQL (SQLEXPRESS)[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 04, 2006 6:53 am 
Regular
Regular

Joined: Fri Nov 04, 2005 12:37 pm
Posts: 81
Hi

I might be stating the obvious here but have your ensured that your mapping file is set as an embedded resource in Visual Studio 2005?

Bosh


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 04, 2006 6:53 am 
Regular
Regular

Joined: Fri Nov 04, 2005 12:37 pm
Posts: 81
Hi

I might be stating the obvious here but have your ensured that your mapping file is set as an embedded resource in Visual Studio 2005?

Bosh


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 04, 2006 7:01 am 
Beginner
Beginner

Joined: Tue Nov 28, 2006 4:26 pm
Posts: 32
Location: Montreal, Quebec, Canada
Good point. I already had it like that since I had the project running with NHibernate 1.0.3. I just changed it to 1.2 Beta 2 and it was all of a sudden unable to find the named queries. Has the mapping definition for the web.config change in 1.2?

I am getting a little further though. I manage to get it to give me the following error now. Is Proxy enabled by default in 1.2 Beta 2?

Parser Error Message:
Code:
NHibernateProvider: unable to get application; operation failed with error "The type initializer for 'NHibernateProvider.Helper.NHibernateHelper' threw an exception".

Base Exception Message:
Code:
"Type 'NHibernateProvider.Entity.Application' cannot be specified as proxy: method get_Id should be virtual"

Base Exception Stack Trace:
Code:
at NHibernate.Proxy.ProxyTypeValidator.Error(Type type, String reason) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Proxy\ProxyTypeValidator.cs:line 28
  at NHibernate.Proxy.ProxyTypeValidator.CheckMethodIsVirtual(Type type, MethodInfo method) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Proxy\ProxyTypeValidator.cs:line 76
  at NHibernate.Proxy.ProxyTypeValidator.CheckEveryPublicMemberIsVirtual(Type type) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Proxy\ProxyTypeValidator.cs:line 63
  at NHibernate.Proxy.ProxyTypeValidator.ValidateType(Type type) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Proxy\ProxyTypeValidator.cs:line 22
  at NHibernate.Cfg.Configuration.ValidateProxyInterface(PersistentClass persistentClass) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Cfg\Configuration.cs:line 917
  at NHibernate.Cfg.Configuration.Validate() in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Cfg\Configuration.cs:line 893
  at NHibernate.Cfg.Configuration.BuildSessionFactory() in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Cfg\Configuration.cs:line 1037
  at NHibernateProvider.Helper.NHibernateHelper..cctor() in D:\Projects\Src\NHibernateProvider\NHibernateProvider\Helper\NHibernateHelper.cs:line 27


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 04, 2006 8:11 am 
Beginner
Beginner

Joined: Tue Nov 28, 2006 4:26 pm
Posts: 32
Location: Montreal, Quebec, Canada
Well, I decided to dig into the readme file in more detail, specifically looking for "proxy". I also added the NHibernate source as part of my solution to debug. It turns out that by default proxy validation is enabled. It verifies that public properties are defined as virtual. I added the following property to my Web.config:

Code:
<property name="use_proxy_validator">false</property>

However, now I get the following error, which leads me to believe that even though I turned off proxy validation it still expects it enabled. Is this a feature or a bug? Perhaps I need to turn something else off.

Parse Error Message:
Code:
NHibernateRoleProvider: unable to find user in role; operation failed with error "Creating a proxy instance failed".

Base Exception Message:
Code:
"Access is denied: 'NHibernateProvider.Entity.Application'."

Base Exception Stack Trace:
Code:
at System.Reflection.Emit.TypeBuilder.TermCreateClass(Int32 handle, Module module) at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.TypeBuilder.CreateType() at Castle.DynamicProxy.Builder.CodeBuilder.AbstractEasyType.BuildType() at Castle.DynamicProxy.Builder.CodeGenerators.BaseCodeGenerator.CreateType() at Castle.DynamicProxy.Builder.CodeGenerators.ClassProxyGenerator.GenerateCode(Type baseClass, Type[] interfaces) at Castle.DynamicProxy.Builder.DefaultProxyBuilder.CreateClassProxy(Type theClass, Type[] interfaces) at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type baseClass, Type[] interfaces, IInterceptor interceptor, Boolean checkAbstract, Object[] argumentsForConstructor) at NHibernate.Proxy.CastleProxyFactory.GetProxy(Object id, ISessionImplementor session) in D:\Projects\Src\NHibernateProvider\NHibernate-1.2\Proxy\CastleProxyFactory.cs:line 58 at System.Web.Administration.WebAdminPage.CallWebAdminHelperMethod(Boolean isMembership, String methodName, Object[] parameters, Type[] paramTypes) at ASP.security_users_edituser_aspx.__DataBinding__control14(Object sender, EventArgs e) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ASP.NETWebAdminFiles\Security\Users\editUser.aspx:line 232 at System.Web.UI.Control.OnDataBinding(EventArgs e) at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) at System.Web.UI.Control.DataBind() at System.Web.UI.Control.DataBindChildren() at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) at System.Web.UI.Control.DataBind() at System.Web.UI.WebControls.Repeater.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem) at System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) at System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) at System.Web.UI.WebControls.Repeater.DataBind() at ASP.security_users_edituser_aspx.PopulateCheckboxes() in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ASP.NETWebAdminFiles\Security\Users\editUser.aspx:line 53 at ASP.security_users_edituser_aspx.Page_Load() in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ASP.NETWebAdminFiles\Security\Users\editUser.aspx:line 34 at System.Web.Util.CalliHelper.ArglessFunctionCaller(IntPtr fp, Object o) at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 04, 2006 11:58 am 
Regular
Regular

Joined: Fri Nov 04, 2005 12:37 pm
Posts: 81
Hi

I have got the same error on the odd occasion in the past:

Code:
  "Type 'NHibernateProvider.Entity.Application' cannot be specified as proxy: method get_Id should be virtual"



This can be fixed by setting you the lazy attribute to false in your class property in your mapping file. But i dont have any deep understanding why this fixes the problem.

Again i have read about this elsewhere on this forum, might be worth doing a search.

Bosh


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 05, 2006 2:28 pm 
Beginner
Beginner

Joined: Wed Nov 29, 2006 5:33 pm
Posts: 28
Location: Chicago, IL
Hello,

When the proxies are generated, the methods and properties in the class need to be overridden. According to your post, it doesn't look like turning off the validator changes that fact.

You should just be able to declare all of your properties and methods as virtual (overridable in VB) and it should solve that error.

Another approach would be to add the attribute and value lazy="false" to your class or joined subclass elements. This prevents a proxy from being generated on a class by class basis. I don't know if there is a way to turn off proxies on a per SessionFactory basis.

For us, turing off the proxies would be a huge performance hit. I can understand why it's the default now. If you don't need it, you'll never know they're there. Unless you're upgrading from 1.0.3 of course =).

Code:
<class name="Thing" table="`Thing`" lazy="false">



Chuck


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 05, 2006 2:51 pm 
Beginner
Beginner

Joined: Tue Nov 28, 2006 4:26 pm
Posts: 32
Location: Montreal, Quebec, Canada
Thanks for the explanation. I tried the lazy="false" and it does do the trick. It must be a work-in-progress. For now, this helps me get the code working using NHibernate 1.2. Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 06, 2006 8:44 am 
Beginner
Beginner

Joined: Wed Nov 01, 2006 5:33 pm
Posts: 22
Lazy instantiation requires proxy stub objects which are derrived classes from your domain object. Therefore you have to declare your properties as overridable (virtual) to use lazy loading. The change from the previous version of NHibernate is simply the default behaviour as Lazy is now set to true by default if not specified.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 18, 2007 10:35 pm 
Newbie

Joined: Wed Sep 06, 2006 10:35 am
Posts: 14
tunic wrote:
Lazy instantiation requires proxy stub objects which are derrived classes from your domain object. Therefore you have to declare your properties as overridable (virtual) to use lazy loading. The change from the previous version of NHibernate is simply the default behaviour as Lazy is now set to true by default if not specified.


I am probably missing something ... but I used the same code with 1.0 and the properties in my mapped classes were not virtual and I did set the lazy attribute to true in the mapping file:

Code:
<class name="myClass, myAssembly" table="myTable" lazy="true">


everything seemed to work fine, but now with 1.2beta3 I get the "method .... should be virtual" error


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 3:48 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
pastafarian wrote:
tunic wrote:
Lazy instantiation requires proxy stub objects which are derrived classes from your domain object. Therefore you have to declare your properties as overridable (virtual) to use lazy loading. The change from the previous version of NHibernate is simply the default behaviour as Lazy is now set to true by default if not specified.


I am probably missing something ... but I used the same code with 1.0 and the properties in my mapped classes were not virtual and I did set the lazy attribute to true in the mapping file:

Code:
<class name="myClass, myAssembly" table="myTable" lazy="true">


everything seemed to work fine, but now with 1.2beta3 I get the "method .... should be virtual" error


Version 1.0 did not verify that the methods/properties were virtual. Still, in order to trigger lazy loading, the accessed meber needed to be virtual.

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 3:47 pm 
Contributor
Contributor

Joined: Sat Sep 24, 2005 11:25 am
Posts: 198
That was actually a serious problem to have in 1.0 in many cases.

1.2 would validate that the class can be proxied correctly, which is a Good Thing.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 6:37 pm 
Newbie

Joined: Wed Sep 06, 2006 10:35 am
Posts: 14
Ayende Rahien wrote:
That was actually a serious problem to have in 1.0 in many cases.

1.2 would validate that the class can be proxied correctly, which is a Good Thing.


Thanks for the response. It makes sense. Obviously this also means your calsses can not be sealed if you want to use lazy loading.

So to be able to use lazy loading, is the rule of thumb that every public property and every public method in the mapped class and all of its ancestor classes must be declared virtual? This is what I am observing that if the mapped class derives from some other class, all the inherited methods must be declared virtual too. Is that right?

It would've been nice if we only had to make the mapped public properties virtual and leave the rest of the classe and its parent class untouched.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 20, 2007 3:31 am 
Contributor
Contributor

Joined: Sat Sep 24, 2005 11:25 am
Posts: 198
Every public /protected/ internal method, actually.
And no, it can't be just mapped properties.
The way NHibernate works, the real object is created behind the scenes, and all the calls are forwarded to it, not loading the values into the current object.


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