-->
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.  [ 13 posts ] 
Author Message
 Post subject: NHibernate and Visual Web Developer 2005 Express
PostPosted: Tue Apr 04, 2006 10:31 am 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
After coming up with a cascading chain of "no-can-do" situations regarding the use of NHibernate under Visual Web Developer 2005 Express I am at my wit's end.

1) I would like to learn to use NHibernate, therefore I have looked through all examples I could find on the web
2) I would like to use NHibernate to develop websites using Web Developer Express
3) All examples I have run across assume you can set hbm mapping files to be embedded, this is not possible for Web Projects that are handled differently from other projects
4) Using separate projects to develop the business logic is not an option since Web Developer Express does not support it
5) Installing Visual c# Express alongside Visual Web developer is not possible due to conflicts according to the MS website

Has anyone else run into similar problems and found a solution? I feel like I have run out of options here...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 04, 2006 10:42 am 
Beginner
Beginner

Joined: Tue May 17, 2005 7:25 pm
Posts: 43
Location: Somewhere, USA
You don't *have* to use the embedded resource approach. You can also opt to load the hbm.xml files manually using the Configuration class from NHibernate. The main reason the docs talk about embedding the xml files is becuase that is the most common scenario. It not required, just common.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 04, 2006 11:05 am 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
I understand that I do not have to. However being new to Visual Web Developer as well as NHibernate does not make this easy at all. I have tried using something like:

[code]
NHibernate.Cfg.Configuration config = new NHibernate.Cfg.Configuration();
config.AddXmlFile(Request.PhysicalApplicationPath + "/App_Data/BusinessUnit.hbm.xml");
factory = config.BuildSessionFactory();
Application["SessionFactory"] = factory;
[code]

Unfortunately this has mainly resulted in all sorts of errors. Mainly the server not knowing the class.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 04, 2006 11:41 am 
Beginner
Beginner

Joined: Tue May 17, 2005 7:25 pm
Posts: 43
Location: Somewhere, USA
Can you post more detail about you errors?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 4:58 am 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
Code:
NHibernate.MappingException was unhandled by user code
  Message="persistent class Concept.BusinessUnit, Concept not found"
  Source="NHibernate"


This leads me to believe I have done something wrong in my mapping file. I have created a project (in Web Developer Express) with the name Concept, which should as far as I know should then also be the assembly name. The class to be mapped is called BusinessUnit.cs and resides in my App_Data subdirectory.

I use the following to locate the class in my mapping file:
Code:
<class name="Concept.BusinessUnit, Concept"
    table="BusinessUnit">


This is in the format fully specified name of the class followed by assembly name afaik.

I am sure it is something offensively simple, but not being able to follow any of the freely available tutorials on the web kind of leaves me to make it work by trial and error.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 8:12 am 
Regular
Regular

Joined: Mon Mar 20, 2006 10:49 pm
Posts: 59
Try just using the class name in the mapping file, e.g.,

<class name="BusinessUnit" table="BusinessUnit">

_________________
Mike Abraham


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 8:20 am 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
Unfortunately that results in a similar error:
Code:
NHibernate.MappingException was unhandled by user code
  Message="persistent class BusinessUnit not found"
  Source="NHibernate"


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 8:32 am 
Regular
Regular

Joined: Mon Mar 20, 2006 10:49 pm
Posts: 59
I took a quick look at the binding logic, and I see why my suggestion was bogus. It first checks if the class is in an already loaded assembly and if it is, it's done. If it's not, it tries to load the assembly, by name, and since we don't know what the assembly name is (apparently not Concept), it fails.

This is a shot in the dark, but why don't you try referencing the class before binding, e.g., BusinessUnit b = new BusinessUnit() or execute some static method, if BusinessUnit has any. That will cause the assembly to be loaded.

_________________
Mike Abraham


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 10:07 am 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
An interesting suggestion. However the assembly name is hardcoded into the mapping file using either the assembly property in the hibernate-mapping root node of the mapping file or the name property of class nodes.

After a very extensive search on the web I came across a very usefull article on the DotNetNuke blogs which basically explains why problems such as this exist with the new style VS web projects. Apparently the code behind pages and the code in your App_Code folder gets compiled into an assembly with a random hashcode style name. The way around this is using class library projects for your data access and business objects layer so you have control over the assembly names. Unfortunately Visual Web Developer 2005 Express can only generate web projects so this workaround is not available.

Quote:
Web Projects do not allow you to create assemblies with custom names. Instead they generate their own assembly names ( the format depends on whether you are using the FixedNames options or not - but either way the name contains a hash code which is autogenerated ). When you are creating components which are dynamically invoked using Reflection, you often require a full TypeName - which requires an assembly name. Sounds a little like the recursive chicken-before-the-egg dilemma, doesn't it. To solve this problem, you can use Class Library projects exactly the same way you did in VS 2003, as they provide the means to custom name your DLLs. The only caveat is that you can not create Class Libraries in Visual Web Developer ( you need VB Express or a more advanced VS 2005 SKU ).

from: DotNetNuke.com

If anyone is able to get NHibernate working under Visual Web Developer 2005 Express I'd be happy to hear from you.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 12:03 pm 
Regular
Regular

Joined: Mon Mar 20, 2006 10:49 pm
Posts: 59
This is a gross hack and I tested it using Visual Studio Pro, but it should work with the Express edition.

The basic idea is to load the mapping doc and replace the name attribute of the class element with the Assembly qualified name determined at run-time.

Code:
        Type type = typeof(Test);
        NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
        XmlDocument doc = new XmlDocument();
        doc.Load(Request.PhysicalApplicationPath + "/App_Code/Test.hbm.xml");
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("hbm", "urn:nhibernate-mapping-2.0");
        XmlNode n = doc.DocumentElement.SelectSingleNode("hbm:class", nsmgr);
        XmlAttribute a = n.Attributes["name"];
        a.Value = type.AssemblyQualifiedName;
        cfg.AddDocument(doc);
[/code]

_________________
Mike Abraham


Top
 Profile  
 
 Post subject: NHibernate and VS2005
PostPosted: Wed Apr 05, 2006 5:30 pm 
Newbie

Joined: Mon Feb 20, 2006 1:08 pm
Posts: 1
Location: Seattle, WA
I've been using NHibernate for the first time on an ASP.NET 2.0 project in VS2005 Professional (not Express I know, but the Web project infrastructure is the same). I have had great success by completely isolating the NHibernate business classes and separate "model" (business logic) and "DataAccess" (data...go figure!) layer. In that way the ASP.NET application doesn't really to know anything about NHibernate at all apart from the basic config for connection string and database backend. I made extensive use (cut'n'paste) of some great work by Benjamin Day http://blog.benday.com/archive/2005/10/25/3054.aspx, although I did convert it all to VB.NET. I don't have a way of posting code to a web site but let me know if you want to check out the application code. It seems to work very well in a low volume (Intranet) environment, and apparently will scale up nicely.

Dylan


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 6:01 pm 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
@mabraham:

First of all: thanks so much for trying to help me resolve this issue. I have taken your code and changed it a little. The reason why is that the name attribute of the class node is not all that needs to be changed. However I did read that you can set a default namespace and assembly in the root node of the mapping file so I adapted it to do exactly that:
Code:
Type type = typeof(Symtech.BusinessObjects.BusinessUnit);
NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
XmlDocument doc = new XmlDocument();
doc.Load(Request.PhysicalApplicationPath + "/App_Code/BusinessUnit.hbm.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("hbm", "urn:nhibernate-mapping-2.0");
XmlNode n = doc.DocumentElement;
System.Diagnostics.Debug.WriteLine("Assembly:" + type.AssemblyQualifiedName);
System.Diagnostics.Debug.WriteLine("Nr of attributes: " + n.Attributes.Count.ToString());
XmlAttribute a = n.Attributes["assembly"];
a.Value = type.AssemblyQualifiedName;
cfg.AddDocument(doc);

Mapping file:
Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="Symtech.BusinessObjects" assembly="">

The code seems to be altering the mapping file fine and also seems to propagate the default assembly, however it still cannot find the class even though it obviously gets assigned the fully qualified assembly name judging by the debug output and, unfortunately, the error message.
Code:
NHibernate.MappingException was unhandled by user code
  Message="persistent class Symtech.BusinessObjects.BusinessUnit, Symtech.BusinessObjects.BusinessUnit, App_Code.u2gcijeu, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null not found"
  Source="NHibernate"


@Dylan:
Yes, if I had VS2005 Pro at my disposal these workarounds wouldn't be neccesary as I would create separate projects (library projects) to handle said tiers. Unfortunately Web Developer will only create web projects without the option to control the resulting assembly names.
Are you sure you have your DAL and domain model residing inside the web project and not in separate projects? If so I would indeed be very interested to see how it's done!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 6:11 pm 
Newbie

Joined: Tue Apr 04, 2006 4:47 am
Posts: 18
Ok got it! Appears that NHibernate cannot handle the FQN of the assembly so instead I have used:
Code:
XmlNode n = doc.DocumentElement;
n.Attributes["assembly"].Value = type.Module.ToString();
n.Attributes["namespace"].Value = type.Namespace;
cfg.AddDocument(doc);

This seems to work! Now I'll just have to iron out the lil bumps like missing setters etc. Thank you all for all your trouble!


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