Click here to Skip to main content
Click here to Skip to main content

NHibernate in real world applications

By , 11 Nov 2004
 

Example Application Screenshot

Introduction

Hibernate has been huge in the Java world for being a easy to use high performance OR mapper, but only recently has it started to make a name for itself in the .NET world with NHibernate.

I've personally had a fair amount with different OR mappers, and object persistence frameworks. I decided to jump in and play with alpha .4 of NHibernate... and have honestly found it to be quite capable and relatively low on bugs (I haven't found any yet anyway).

Background

After reading a couple of articles here (NHibernate) on the subject of NHibernate, I had a general clue, but probably more questions then answers.

I decided about bundling some real world examples along with explanation of why I am doing what, and it should be a pretty good starting point for anyone wanting to dive into OR Mappers, whether it be hobby or an enterprise application.

I'll start out first by saying, initially my work was based of these examples, however... I've found that the examples were sometimes incorrect, or files weren't named, or procedures weren't explained. Anyhow I aim to help with that!

Article Goals

This is my first submission of any kind, so keep non-constructive criticism to a minimum. I am 100% open to feedback, I don't claim to have all the answers, or claim to have the best methods to achieve this or that.

Over the next couple in a series of articles, I'd like to demonstrate n-tier frameworks utilizing NHibernate.

In this part, it'll be a basic data layer logic that I will be referencing directly for the time being, but in later articles, I intend to implement my business logic layer, as well as security on my business methods.

Target audience... anyone who is interested in N-Tier development. As I said before, it'll help hobbyists, and people interested in getting started in enterprise development. As well as, maybe fill in a little bit where I struggled (because of lack of documentation). I'd also like to provide a starting point for people who are just getting into building robust applications (whether for business or hobby... no excuse for bad application design).

Getting Started...

These steps are required, however, the order in which you do them is debatable.

Database Schema - I am using the Northwind database that is so standard, or downloadable from Microsoft. For now, I only really need Customers and Orders, the others are not necessary.

Northwind Schema

Class Definitions - You need to write a class with at least one constructor that has 0 parameters, and public properties representing data in the database: Bags, or Collections (Customer.Orders will end up being a IList after everything is said and done, we'll go into this a little more later...).

Customer.cs

using System;
using System.Collections;

namespace nhibernator.BLL
{
    /// <SUMMARY>
    /// Summary description for Customer.
    /// </SUMMARY>
    public class Customer
    {
        #region Private Internal Members
        
        private string m_CustomerID, m_CompanyName, m_ContactName, 
                m_Address, m_City, m_Region, m_PostalCode, m_Country;
        private IDictionary m_Orders;
        #endregion
        
        #region Public Properties

        public string CustomerID
        {
            get
            {
                return m_CustomerID;
            }
            set
            {
                m_CustomerID = value;
            }

        }

        public string CompanyName
        {
            get
            {
                return m_CompanyName;
            }
            set
            {
                m_CompanyName = value;
            }
        }

        public string ContactName
        {
            get
            {
                return m_ContactName;
            }
            set
            {
                m_ContactName = value;
            }
        }


        public string Address
        {
            get
            {
                return m_Address;
            }
            set
            {
                m_Address = value;
            }
        }
        
        public string City
        {
            get
            {
                return m_City;
            }
            set
            {
                m_City = value;
            }
        }

        public string Region
        {
            get
            {
                return m_Region;
            }
            set
            {
                m_Region = value;
            }
        }

        public string PostalCode
        {
            get
            {
                return m_PostalCode;
            }
            set
            {
                m_PostalCode = value;
            }
        }

        public string Country
        {
            get
            {
                return m_Country;
            }
            set
            {
                m_Country = value;
            }
        }
        
        public IDictionary Orders
        {
            get
            {
                return m_Orders;
            }
            set
            {
                m_Orders = value;
            }
        }

        #endregion
        
        public Customer()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }
}

Ok, so now we have Customer class defined, we'll want to more or less duplicate this with Products, and orders.

Mapping file - <ClassName>.hbm.xml to be built as an embedded resource (defines how our Entities map to database objects).

You'll need one of these for each class you intend on persisting. Sounds time consuming, but comparing alternatives, it's relatively pain free.

Customer.hbm.xml

<HIBERNATE-MAPPING" xmlns="urn:nhibernate-mapping-2.0">
    <CLASS name="nhibernator.BLL.Customer, nhibernator" table="Customers">

        <ID name="CustomerID" column="CustomerID" type="String" length="20"> 
            <GENERATOR class=assigned /> 
        </ID> 
        <!-- Map properties I'd like to persist/fetch, 
            assume column = propery name, 
            and type is determined by reflection -->
        <property name="CompanyName"></property> 
        <property name="ContactName"></property> 
        <property name="Address"></property>
        <property name="City"></property>
        <property name="Region"></property>
        <property name="PostalCode"></property>
        <!-- Orders collection, pull customer orders but,
           loading lazy to minimize load time, resource usage. -->
        <SET name="Orders" cascade="all" lazy="true">
            <KEY column="CustomerID" />
            <ONE-TO-MANY class="nhibernator.BLL.Order, nhibernator" />
        </SET>
    </CLASS>
</HIBERNATE-MAPPING>

Unfortunately, Northwind has some questionable design practices. However, it's everywhere and thus I think it to be the perfect database for this example.

Normally, CustomerID, the ID field in Customer would be int or GUID, and unique int, and would have slightly different syntax. However, in this case it does not.

We can effectively "Alias" table field names to class properties like so:

<property name="CompName" column= "CompanyName" type="String" length="40"/>

However, I'd like to stick to database fields as much as possible. You can actually omit the column all together if you want the property to have the same name...

<property name="CompanyName" length="40"/>

You might also notice I've removed the type="string" bit of text. As of recent versions anyway NHibernate uses reflection to determine the type of the data (perhaps there are some performance ramifications, though really don't know).

Important note...

While you could probably load the mappings on the fly by specifying a filename, it seems to be a general practice to compile to embedded resource. Once you've created your .hbm.xml, make sure your build action is Embedded Resource like so:

build action

So now, I leave you to write the mapping files for the other two persisted objects, or you can simply download the code!

NHibernate configuration - can be done through XML file, resource stream, or manually in code. (I chose the code route, as trial and error with other methods never worked as they should; don't know if this is error on my part, or side effect of being an alpha).

NHibernate needs to be told what database provider to use, what SQL dialect to use, and connection string. Normally, a config file would look like this:

<?xml version="1.0" encoding="utf-8" ?>
<HIBERNATE-CONFIGURATION xmlns="urn:nhibernate-configuration-2.0">
    <SESSION-FACTORY name="nhibernator">
        
        <property name="connection.provider">
            NHibernate.Connection.DriverConnectionProvider
        </property>
        <property name="connection.driver_class">
            NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">
            Server=localhost;initial catalog=Northwind;Integrated Security=SSPI
        </property>
        <property name="show_sql">false</property>
        <property name="dialect">
            NHibernate.Dialect.MsSql2000Dialect
          </property>
        <property name="use_outer_join">true</property>
        <property name="query.substitutions">
            true 1, false 0, yes 'Y', no 'N'
        </property>
        
        <MAPPING assembly="nhibernator" />
    </SESSION-FACTORY>
</HIBERNATE-CONFIGURATION>

However, like I said, I couldn't get the embedded resource stream for that to work, so I've written up the following code to simulate it. (Not as easy to come along and change later, but sufficient for getting the idea across).

In my data layer class CustomerFactory.cs, I have this code in the constructor for the time being:

config = new Configuration();
            IDictionary props = new Hashtable();

props["hibernate.connection.provider"] = 
     "NHibernate.Connection.DriverConnectionProvider"; 
props["hibernate.dialect" ] = "NHibernate.Dialect.MsSql2000Dialect"; 
props["hibernate.connection.driver_class"] = 
     "NHibernate.Driver.SqlClientDriver" ;
props["hibernate.connection.connection_string"] = 
     "Server=localhost;initial catalog=Northwind;Integrated Security=SSPI" ;

foreach( DictionaryEntry de in props ) 
{
    config.SetProperty( de.Key.ToString(), de.Value.ToString() );
}

config.AddAssembly("nhibernator");

*Log4Net configuration - sure you could skip this, but then good luck making sense of errors when things don't work =) In my client app, I simply read a log4net.config on load, and start from there.

n-Tiered Frameworks...

If you've encountered any sort of professional or enterprise software development, you've undoubtedly had these concepts beaten into your brain, and probably for the good.

Too much abstraction is bad, but a decent separation of data, business logic, and presentation logic can improve efficiency, code readability, and general upkeep.

So I've created a root namespace, and then created DLL for data layer logic (sure I could have used something a little more informative, but I am a creature of habit).

A subnamespace (?) of BLL for business layer logic...

And finally a whole other project for my presentation logic (I like to know I can use my tiered logic in console, web, remoting, webservices etc.).

DataLayerLogic - By definition, this code really should probably handle getting/updating/inserting/deleting entities in the database as well as data validation (SQL injection proofing etc.)

Luckily, NHibernate handles a fair amount of what's supposed to be done in the data layer itself, and so we generally end up writing some minor data validation, and methods to fetch all, fetch a single entity, or fetch entities based on some criteria.

What I've done is create a separate "factory" for each entity type (CustomerFactory, ProductFactory, OrderFactory). In the constructor, I set up the NHibernate session factory, and spawn a NHibernate isession. Then each method to set/get data checks to see session.IsConnected, and if it's not session.ReConnect(). This is important as data isn't blocked the entire time my data factory is instantiated. I perform the logic, and then disconnect. On dispose of my factory class, I make sure session gets disposed etc.

I've got two methods built out for fetching customers in CustomerFactory.cs.

First... GetCustomers() in which I simply get back an IList of Customer objects.

Secondly... GetCustomer(string CustomerID) in which I feed it an ID such as "BERGS", and since I fetch with FETCHMODE.EAGER flag, I get all the subcollections, without trying to access them.

BusinessLayerLogic - Theoretically, in a lot of cases, simply wrapping DataLayerLogic methods/classes is sufficient. However I end to fire off events, and do extra validation that wouldn't be simple insertion problems.

In this article, I've not really built out this layer; look for it in the next in this series.

PresentationLogic - in this case, I simply create an instance of my DataLayerLogic, or invoke some of the static methods, and update user interface appropriately. (One could use ASP.NET or WinForms, or upcoming XAML or any number of presentation methods here).

I was sort of in a rush in this case; however, my little WinForms app will fetch all customers, and insert hard-coded data as a new user. (I'll make this a lot more presentable in an update to this article.)

Of course, your namespace structure could look totally different (as most people have <companyname>.<technology>.<project>.<feature>), but for all intent and purposes, I've come up with this:

namespace layout

Notice the .hbm.xmls. You can actually throw these in a mappings folder or whatever makes things cleaner for you...

I can simply call a static method and get a collection of Customers which are data-bindable by default.

Where to go from here?

Nhibernate has a wealth of different configuration options for caching and performance tweaking, which I will get into in my second article. Unfortunately, there isn't a whole lot of documentation on the subject, so you can try looking at hibernate documentation.

Also in the next article, you can expect to see a mechanism for my n-tier BusinessLayerLogic to check credentials for fetching the data.

In closing...

Like I said, I struggled with NHibernate. Getting it up and running the first time can be quite a pain; however, it can be done. The example works, but you'll probably want to download NHibernate separately from here and add nhibernate.dll to your "References".

Again, please leave constructive criticism only. This is my first article, and I realize it was on a broad subject. Thanks, and keep your eyes open for part 2!

History

v1 - First version of the article. No bugging me about layout, I'm working on it. Documentation too!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

ronnyek
United States United States
Member
I've been involved with software development since teaching Basic to teachers in 6th grade. Since then I've been involved with every aspect of computers.
 
Lately, I've involved myself very much in building Entperise Java and .Net applications.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionwhich database used?memberAarti Meswania20 Feb '13 - 0:40 
It is not working
please give suggesion
GeneralMy vote of 4memberyasar.facebook23 Nov '10 - 5:36 
I'm the new one in nhypernate
it is very useful for me.
Questionhow to save an xml( an embedded resource) in project?memberTarun.K.S12 Oct '10 - 0:26 
i am having trouble saving my xml which is stored as an embedded resource in my vb.net project..
m able to load the xml by reading the xml through a resource reader but not able to write to the xml coz while writing using streams it says "stream does not support writing".. Frown | :(
 
thanks for your help,
Tarun
Generalplease help me in simple nhibernate projectmembersaeedmain22 Aug '10 - 4:06 
Hello my friends
I am a beginner in nhibernat.and I should develop an nhibernate project.
In first step I want read a table from database and show its rows in a gridview.
The table name is PGroup . the below method has problem and when run the bold line throws an exception(Object reference not set to an instance of an object) .
The method is:
---------------------------------------------------------------------------
public static List LoadGroup(string query)
{
try
{
session = OpenSession();
IQuery iquery = session.CreateQuery(query);
IList result = iquery.List();
List result_list = result.ToList();
session.Close();
return result_list;
}
catch (Exception ex)
{
return new List();
}
}

------------------------------------------------------------------------------
This method has called from below method:
public static List LoadAllGroups()
{
string query = "from PGroup as p order by p.groupID asc";
List result = Common.LoadGroup(query);
return result;
}

I don’t know what should do!i check classes, mapping files,hbm.xml files
and set them as embeded references.but it doesn’t work.
Please help me. D'Oh! | :doh:
GeneralRe: please help me in simple nhibernate projectmemberjseee_7 Sep '10 - 21:56 
try this :
public IList<T> GetAll<T>(string sortProperty , bool ascending , int idUser) {
using (ISession session = sessionFactory.OpenSession()) {
IList<T> listOfObjects = null;
try {
ICriteria crit = session.CreateCriteria(typeof(T));
if (ascending) {
crit.AddOrder(Order.Asc(sortProperty));
listOfObjects = crit.List<T>();
} else {
crit.AddOrder(Order.Desc(sortProperty));
listOfObjects = crit.List<T>();
}
return listOfObjects;
} catch (HibernateException exc) {
//exceptions
}
}
return (IList<T>)new object();
}
GeneralNeed for helpmembera_kiani24 Oct '09 - 22:37 
I have a problem with NHibernate 2.2 in my project.
My Problem: I have a class 'Order' which contains an instance from another class, 'User'. 'User' is defined in a separate assembly.
Also, the table relevant to 'User' is in a separate database.
How should I write the mapping file?
Thanks in advance
GeneralPlease answermemberMember 159112712 Oct '09 - 5:12 
Nice article Smile | :)
 
From past few days i am continuously looking for ORM's/frameworks and came across many like Castle (castleproject.org),Sharp Architecture, Spring etc..I have seen many codes which uses Nhibernate and i have found dll of castle project like Castle.core and spring etc in a project having reference to Nihibernate dll. My questions are
 
1) Does Nhibernate is a combination of all these framework and the other framework dll’s are the part of Nhibernate framework? or we have to follow a certain path to incorporate these frameworks in Nhibernate.
 
2) Each framework or ORM states it's best and could be used as ORM or code modelling tool separately , so can you help me to find the best one?
 
As per the readings done yet i guess SharpArchitecture>Nhibernate>MVC where you can ">" take as "better"
I am also confused with Microsoft Entity framework.
 
Could you suggest me a single framework which has best of all above frameworks(Industry best practices)?
 
3)Does any Nhibernate or Entity framework has the UNIT of work pattern like LLBGenPro.
I know that in Entity Framework they have introduced POCO but is it matured enough?
Generalrename your classesmemberDean Hiller24 May '08 - 20:55 
Also, your Factory classes should be renamed to Dao's instead. They are really just Data Access Objects so may be call it CustomerDao and OrderDao, etc. etc....at least, that's what we typically do in Java.
Generalproblems with zip filememberDean Hiller24 May '08 - 20:53 
there were quite a few problems with the code download, but thanks for the example. It was good enough to start with. I upgraded the hibernate and fixed alot of bugs in the example and I used it with postgres(I like free stuff).
 
1. should not disconnect and reconnect sessions. The proper pattern is to close and open a new one. These sessions ar mini caches and need to be cleared. After all, even java's hibernate in EJB3 got rid of all that stuff and you can't disconnect anymore in EJB3...only close and reopen.
 
2. session.close(in your case disconnect) should be in the finally blocks instead of writing it twice.
 
3. you forgot to commit a few of your transactions so it caused reentrance problems to the methods.
 
4. I could not get IDictionary to work at all and had to switch to an ICollection.
 
I have a new source code version after making all the proper fixes. Have an email I can send it too? dean____at____xsoftware__dot___biz without the ____ stuff Smile | :) .
 
http://xsoftware.biz
QuestionHow to update primary key value (customerid value)memberlpbinh9 Mar '08 - 21:12 
Hello every one, i am a newbie in Nhibernate, i has use Nhibernate to get all cutomers, save/update/delete customer to/from database. And i have a problem when do modify customer information.
When i modify customer information without modify CustomerID value,
it's ok. But when i modify CustomerID, i example i have a customer who have CustomerID is 'RICAR' now i change his CustomerID to 'RICARS' and call Update i get an error " Unexpected row count: 0; expected: 1".
 
My question is have any way to modify the primary key value field and update (CustomerID primary key).
 
And others question is i have a table which have a composite key example Order table have two column is OrderNo, Number is primary key, how to make the mapping file for Order class.
 
Thanks
GeneralCustomerFactory vs. CustomerRepositorymemberÖzgür3 Nov '07 - 23:07 
Hi,
it is a great article to see Nhibernate in Action. Thanks for your effort.
 
I would like to mention some point that can be interpreted wrongly
 
The classes that you are using as Factories are not seeming to be Factory Classes(i assume that Factories are responsible for creating objects.
The responsibility for such data access logic can be put to Repsitory Classes.I think it would be clearer to undesrtand the responsibilities of the classes if you folow the Repository Pattern instead of using classes that you name as Factories.
 
greetings from Germany,
Özgür
GeneralCommunication between BLL and DALmemberVuyiswamb2 Oct '07 - 4:27 
hi Man, it was a Great Article, especial for us Beginers. am new to vb.net , but i have grown. so i deciced to bult all my applications based on BLL and DAl. i was searching for the right article until i find yours. It does not teach me exactly what i want , but it tell me more about DAL and BLL in OOPs. if you dont mind i would like to ask a long Question.
 
Am buliding a windows application. Simple application that Stores data to the SQlDB. So i have a Form that will Accept input. and i have created a class and named it PropertyBLL , thats where i will be doing my validation. i would want to start building a DAL, i would like to collect the validated input from BLL to the DAl. how do i achieve that. here is my code for the class BLL.
Public Class PropertyBLL
    Private num_key As Integer
    Private Extension As Integer
    Private Cell_ID As Integer
    Private Actual_Extent As Integer
    Private Lis_key As String
    Private Func_key As String
    Private Geocode As String
    Private Prop_Category_ID As Integer
    Private Non_Discreet_Valid As Integer
 
    Property Num_keyp() As Integer
        Get
            Num_keyp = num_key
 
        End Get
        Set(ByVal Value As Integer)
            If Value.ToString > 4 Then
                num_key = Value
            Else
                Throw New PropertyException("Num_key should be Four Digits.", "Num key")
            End If
        End Set
    End Property
 
    Property Extensionp() As Integer
        Get
            Extensionp = Extension
        End Get
        Set(ByVal Value As Integer)
            If Value <= 0 Then
                Throw New PropertyException("Extension Not Recognised.", "Extension")
            Else
                Extension = Value
            End If
 
        End Set
    End Property
 
    Property Cell_IDp() As Integer
        Get
            Cell_IDp = Cell_ID
        End Get
        Set(ByVal Value As Integer)
            If Value <= 22 Then
                Cell_ID = Value
            Else
                Throw New PropertyException( _
                "Cell ID Not Recognised.", "Cell ID")
 
            End If
 
        End Set
    End Property
    Property Actual_Extentp() As Integer
        Get
            Actual_Extentp = Actual_Extent
        End Get
        Set(ByVal Value As Integer)
            Actual_Extent = Value
        End Set
    End Property
    Property Lis_keyp() As String
        Get
            Lis_keyp = Lis_key
        End Get
        Set(ByVal Value As String)
            Lis_key = Value
        End Set
    End Property
    Property Func_keyp() As String
        Get
            Func_keyp = Func_key
        End Get
        Set(ByVal Value As String)
            Func_key = Value
        End Set
    End Property
    Property Geocodep() As String
        Get
            Geocodep = Geocode
        End Get
        Set(ByVal Value As String)
            Geocode = Value
        End Set
    End Property
    Property Prop_Category_IDp() As Integer
        Get
            Prop_Category_IDp = Prop_Category_ID
        End Get
        Set(ByVal Value As Integer)
            Prop_Category_ID = GetCategory(Func_key)
        End Set
    End Property
 
    Property Non_Discreet_Validp() As Integer
        Get
            Non_Discreet_Validp = Non_Discreet_Valid
        End Get
        Set(ByVal Value As Integer)
            Non_Discreet_Valid = 1
        End Set
    End Property
    'Constrctor for my Class 
    Sub New()
        Non_Discreet_Valid = 1
 
    End Sub
 
    Function GetCategory(ByVal Func_key As String)
        If Func_key.Substring(5, 5) = "PV000" Then
            Prop_Category_ID = 1
        ElseIf Func_key.Substring(1, 5) = "PVDIF" Then
            Prop_Category_ID = 2
        ElseIf Func_key.Substring(1, 5) = "PVNTR" Then
            Prop_Category_ID = 3
        ElseIf Func_key.Substring(1, 5) = "GEOSS" Then
            Prop_Category_ID = 12
        ElseIf Func_key.Substring(1, 5) = "PVCLP" Then
            Prop_Category_ID = 5
        ElseIf Func_key.Substring(1, 5) = "PVWOP" Then
            Prop_Category_ID = 4
        Else
            MessageBox.Show("We dont Have Any Functional Key like that", "Warning", MessageBoxButtons.OK)
        End If
    End Function
End Class
 
Public Class PropertyException
    Inherits System.ApplicationException
 
    Private mstrFieldInError As String
    Sub New(ByVal strMessage As String, ByVal strFieldInError As String)
        'set the Message for the New Exception
        MyBase.New(strMessage)
        mstrFieldInError = strFieldInError
    End Sub
    Public ReadOnly Property FieldInError() As String
        Get
            FieldInError = mstrFieldInError
 
        End Get
    End Property
 

End Class
 

 
 
Thanks

 
Vuyiswa Maseko,
 
Sorrow is Better than Laughter, it may Sudden your Face, but It sharpens your Understanding
 
VB.NET/SQL7/2000/2005
http://vuyiswamb.007ihost.com
http://Ecadre.007ihost.com
vuyiswam@tshwane.gov.za
 

GeneralEasy mapping (without the codegen)memberawesomeo11 Sep '07 - 19:57 
I followed this article[^] and this one[^] which demo a tool that I think has an nihibernate backend, but with a plugin for VS2005 and an easier to use api. Was pretty cool.
 
A lot of people push code-generators, but imo they generally make a whole bunch of code you can't maintain. Diamond binding is cool because it just has a bunch of attributes on the fields, and hides that in partial classes in your project. Its kinda like how the the form designer works. Really simple interface too - I remember trying llibgen and that was just too confusing, its like i've allready specified all this crap when I designed the database, why are you making me do it again. In diamond binding you just tick the tables you want off a list, and when you change the database you click the blue resync button.
 
Anyway if you want my advice - avoid code-generation like the plague. I don't really think you save any time in the end :P Honestly i dont even feel comfortable with what DB does - although it creates about a tenth of what the form designer does, and I guess you could maintain it by hand pretty easily. Still, I'm lazy and I like the resync button I guess :P
 
I am awesomeo.
Generalhttp://gennit.commemberGary Brewer25 Jun '07 - 12:05 
Hi Ronneyk
 
Very good article explaining the basics of NHibernate. If you get a chance take a look at gennit.com a code generation tool for creating NHibernate classes and HBM mappings. Might come in useful.
 

Thanks for the article,
 
Gary

QuestionSaveOrUpdate()memberCoderByHeart7 May '07 - 1:13 
I tried to get this working but i am getting an exception :
SQL insert, update or delete failed (expected affected row count: 1, actual affected row count: 0). Possible causes: the row was modified or deleted by another user, or a trigger is reporting misleading row count
 
For ex :
Customer customer = new Customer(); // let us assume there is no collection contained in this class
customer.CustomerID = "C100";
// start transaction
ISession.SaveOrUpdate(customer);
// commit transaction -- here it throws the exception

 
'assigned' is specified for generator.
What is expected from this piece of code is insert a new row.
 
Any ideas why it is not working?
 
thanks
AnswerRe: SaveOrUpdate()memberjokiz10 May '07 - 20:48 
use save not saveorupdate for assigned ids
 
(x-a)(x-b)(x-c)...(x-z)

GeneralRe: SaveOrUpdate()memberCoderByHeart15 May '07 - 1:48 
There is a scenario, where i have a lot of objects and without worrying whether to Update or Save, i want to have all those in DB, that's why i thought of SaveOrUpdate().
I am not sure but i think SaveOrUpdate() should not work for sequence id's in which case NHibernate will not be able to determine whether to Save or Update since it doesn't know the key column. On the other hand, for assigned id's i expected it to work since it can get to know whether a particular key exists or not.
 
BTW, thanks for the info.
Generalhbm2ddlmemberEdwill Leighton12 Apr '07 - 12:40 
Thanks, this cleared things up quite a bit for me.
 
Another useful topic for a future article might be using NHibernate.Tool.hbm2ddl.SchemaExport to generate DDL for creation of the database...
GeneralRe: hbm2ddl [modified]memberdennis_decoene30 Jul '07 - 21:28 
For creating and updateing the database schema, I use Migrator. This is a tool built by Marc-André Cournoyer. A genius imho.
 
look at :http://macournoyer.wordpress.com/2006/09/20/database-migration-for-net/[^]
 
Marc is also a very helpful guy. If you would like some more info on how I use it, let me know.
 
It has the same function as db:migrate from Ruby on Rails. This means you can now have your database versioned. So you can: rollback versions, easily rebuild the database schema on another server machine or ie from mysql to ms sql or vice versa, have your schema in subversion,... To know more, I blogged about it on: http://dyonisius.wordpress.com/2007/07/31/database-versioning-for-net/[^] Have a look.
 
Dennis Decoene
ML Solutions bvba
-The Micro-ISV bringing you next generation business software -
http://www.mlsolutions.be
 

-- modified at 9:43 Tuesday 31st July, 2007
GeneralMessage Automatically RemovedmemberIqbal M Khan18 Mar '07 - 23:50 
Message Automatically Removed
GeneralRe: Useful optionmemberronnyek19 Mar '07 - 3:28 
I am pretty sure the purpose of code project is to provide code and howtos to use free/opensource software, not advertise your software. I've got my own ORMAPPER, you dont see me here trying to advertise it.
 
Yes there are options out there... no I dont beleive this is the place to advertise commercial solutions, unless of course you pay the code project to do the product spotlight deal on your software.
GeneralCould not save object..what's happen about NHibernate ? [modified]membertkimji28 Feb '07 - 23:02 
Error:"No persisters for: DataAccess.hibernate.dto.Customer"
 
I tried config Customer.hbm.xml,hibernate.cfg.xml but it error,Can you please help me ?
 

-- modified at 5:08 Thursday 1st March, 2007
 
piyahphon

GeneralAlternative to Persistance MappersmemberXin Zhao13 Feb '07 - 13:36 
Persistance mappers like hibernate are certainly a good way of mapping objects to databases, however it's very time consuming to setup and often the performance is sub-standard. There are also other problems such as use of reflection, weak types, etc...
 
A much better alternative is to use code generation. Code generation based on database schemas can deliver the same or better result than a persistance mapper with 1/10th the development effort.
 
A very good exampe of a code generator would be http://www.codeauthor.org (for C# 2.0).
 
XinXin
GeneralRe: Alternative to Persistance Mappersmemberronnyek13 Feb '07 - 14:29 
Xin,
 
I believe OR mappers serve that MAJORITY of enterprise applications. The beauty of nhibernate is that it can determine mappings via reflection, mapping files, or mapping files compiled as resources.
 
OR mapping can allow for completely agnostic data objects, that is they have to have ZERO knowledge of underlying persistent mechanisms.
 
In addition, or mappers can optimize queries on the fly. NHibernate has optimization stuff in place as well as first and second layer caching to speed up data access even further. Code generation works, however, in my experience code generation introduces whole other layer of complexity including maintenance.
 
On a side note, I'd like to think code project of a place for learning, and open source, not a place to advertise your commercial software. Please advertise elsewhere.
GeneralRe: Alternative to Persistance MappersmemberXin Zhao27 Feb '07 - 1:38 
Ronnyek,
 
I'm not sure if you have ever actually used code generation or if your just guessing, but code generation offers a number of advantages over persistance mapping and there is a strong trend in people moving to code generation especially using the agile methodology. I have programmed using both methodologies for a number of years and although both have advantages and disadvantages, overall for most small-medium (sub $2M products) it's much better using Code Generation.
 
Reasons:
 
1. No matter how fast or optimised a persistance mapper is it will always be slower than code generation in performance. This is mainly because it uses reflection and builds mapping information during run time.
 
2. Code generation builds strongly typed objects. A good generator or template engine also allows the code to be easily modified. So it's MORE mainable and usable not less. Imagine if you had to change the data model, good code generators like codeauthor will automatically re-factor all your existing objects, and manual changes to objects are not overwritten!
 
3. It's much much much much faster to build DAL's using code generation than persistance mapping. (about 10X faster)
 
And on your side note comment. Yes I have built a code generation product and I use it as an example in my arguments. why wouldn't I, i also use my product in many of my applications. The product is also free and can be used by anyone (there is a license for businesses use but what is wrong with that). NHibernate is just another product afterall. I think me having built a software development tool, which in fact does generate open source code, and i have written many examples and reasons supporting the use of code generation on the web (not all of them foucsed on my tool specifically) is more supportive of learning than most.
 
XinXin
http://www.codeauthor.org

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 12 Nov 2004
Article Copyright 2004 by ronnyek
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid