Marc Lehmann

blog

  Home  |   Contact  |   Syndication    |   Login
  9 Posts | 0 Stories | 11 Comments | 4 Trackbacks

News

Archives

Post Categories

Wednesday, July 26, 2006 #

I did not find a lot of information on using NHibernate in combination with a MySQL database. The reason I want to do this at all is quite simple, though: My ISP hosts ASP.NET 2 and MySQL databases. And finding an ISP that hosts SQL-Server 2005 and ASP.NET 2 at a price you can pay when you don't make money with your site is a hard task around here. Apart from that, I don't want my code to be dependent on any database system, and NHibernate provides an excellent way to achieve this goal.

This is not about object relational mapping concepts. It also does not explain too much about NHibernate. You can get a lot of information about NHibernate from the NHibernate website.

So let's do a Test-Case (I very much like writing so called learning tests to explore stuff). I'm using SharpDevelop V. 2.0.0 and NUnit for this example.

First, I create a dummz-table on my MySQL database:

CREATE TABLE `dummytable` (
  `id` char(32) collate latin1_german1_ci NOT NULL,
  `text` varchar(255) collate latin1_german1_ci NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci COMMENT='Table for NHibernate example';
This is pretty much a simplyfied version of the Cat-Table used in the NHibernate quickstart.

Then I write my Domain-Model class (bit a big word for something like this, but...), which look like this:

using System;

namespace LearningTests
{
	public class Dummy
	{
		private string id;
		private string text;

		public Dummy()
		{
		}
		
		public string Id {
			get{ return id;}
			set{ id = value;}
		}
		
		public string Text {
			get{return text;}
			set{text=value;}
		}
	}
}

I also need a mapping file that defines how a Dummy instance is populated with information from the database, and how an instance is persisted to the database in turn. I call this file Dummy.hbm.xml. In this first step, set the copy property to "Copy Always".

<?xml version="1.0"?>:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
	<class name="LearningTests.Dummy, LearningTests" table="dummytable">
		<id name="Id">
			<column name="id" sql-type="char(32)" not-null="true"/>
			<generator class="uuid.hex" />
		</id>
	
		<property name="Text">
			<column name="text" length="255"/>
		</property>

	</class>
</hibernate-mapping>

Then I need the test case. I create one simple test that looks as follows. Since the configuration file caused me some troubles, I first configure Hibernate programmatically, which is not the preferred way to do things!

using System;
using System.Collections;

using NUnit.Framework;

using NHibernate;
using NHibernate.Cfg;

namespace LearningTests.Tests
{
	[TestFixture]
	public class Test1
	{
		[Test]
		public void TestMethod()
		{
			Configuration config = new Configuration();
			IDictionary props = new Hashtable();
			String connectionString = "Server=server;Database=dbName;User ID=user;Password=passwd";
			props.Add("hibernate.dialect", "NHibernate.Dialect.MySQLDialect");
			props.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
			props.Add("hibernate.connection.driver_class", "NHibernate.Driver.MySqlDataDriver");
			props.Add("hibernate.connection.connection_string", connectionString);
			config.AddProperties(props);
			config.AddFile("Dummy.hbm.xml");
			ISessionFactory factory = config.BuildSessionFactory();
			ISession session = factory.OpenSession();
			
			int countBefore = getDummyTableSize(session);
			
			ITransaction tx = session.BeginTransaction();
			Dummy d = new Dummy();
			d.Text = "test text";
			session.Save(d);
			tx.Commit();
			
			Assert.AreEqual(countBefore+1, getDummyTableSize(session));
			session.Close();
		}
		
		private int getDummyTableSize(ISession session) {
			ITransaction readTx = session.BeginTransaction();
			int size = session.CreateQuery("from Dummy").List().Count;
			readTx.Rollback();
			return size;

		}
	}
}

In order to run this code, I need to match a few requirements:

  • I need the NHibernate library, downlodable here
  • I also need the MySQL Connector Net library which you can get here. Notice that the installer-download contains an msi that installs the libraries into the GAC. Notice also that the no-installer download contains the binaries for Mono, .Net 1.0 and 1.1, but not for .NET 2.
Now the green bar appears - Jippee!

But as I said, configuring Hibernate in the code is not really the preferred way to do things. It's much better to create a configuration file for Hibernate. I call it hibernate.cfg.xml and add it to the root of your test project. I also set it's copy property to "Copy Always".

<?xml version="1.0" encoding="latin1"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.0">
	<session-factory>
		<property name="dialect">NHibernate.Dialect.MySQLDialect
		<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider
		<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver
		<property name="connection.connection_string">Server=server;Database=dbName;User ID=user;Password=passwd
	</session-factory>
</hibernate-configuration>

This makes TestMethod shrink to the following:

		[Test]
		public void TestMethod()
		{
			Configuration config = new Configuration();
			config.Configure();
			config.AddFile("Dummy.hbm.xml");
			ISessionFactory factory = config.BuildSessionFactory();
			ISession session = factory.OpenSession();
			
			int countBefore = getDummyTableSize(session);
			
			ITransaction tx = session.BeginTransaction();
			Dummy d = new Dummy();
			d.Text = "test text";
			session.Save(d);
			tx.Commit();
			
			Assert.AreEqual(countBefore+1, getDummyTableSize(session));
			session.Close();
		}

Now it's going to get even better. I currently still add the mapping file programmatically to our configuration. I can do this in the hibernate.cfg.xml file as well. For this I set the mapping file's build action to "Embedded Resource" and then change the hibernate config like this:


<hibernate-configuration xmlns="urn:nhibernate-configuration-2.0">
	<session-factory>
		<property name="dialect">NHibernate.Dialect.MySQLDialect
		<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider
		<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver
		<property name="connection.connection_string">Server=mysql4.webland.ch;Database=blueDB12;User ID=wl19www79;Password=746218
	
		<mapping assembly="LearningTests" />
	</session-factory>
</hibernate-configuration>

Like this I let NHibernate know that the LearningTests assembly contains mapped classes. Since I named the mapping and class file similarly and placed them next to each other, NHibernate now finds the mappings itself. This means another line in my TestMethod has gone:

		[Test]
		public void TestMethod()
		{
			Configuration config = new Configuration();
			config.Configure();
			ISessionFactory factory = config.BuildSessionFactory();
			ISession session = factory.OpenSession();
			
			int countBefore = getDummyTableSize(session);
			
			ITransaction tx = session.BeginTransaction();
			Dummy d = new Dummy();
			d.Text = "test text";
			session.Save(d);
			tx.Commit();
			
			Assert.AreEqual(countBefore+1, getDummyTableSize(session));
			session.Close();
		}
Once the stuff is set up right, NHibernate is a really great tool to work with, I think. Even if it's not as mature as it's big sister Hibernate, of which it is a port.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Friday, November 18, 2005 #

Just found this page http://www.dead-links.comhttp://www.dead-links.com which performes link checks on an url. It seems to be quite valuable as it follows all the internal links first, then all the external links and finally creates a report of all detected failures. This means it is sufficient to run the test on the entry page of a site - it will transitively check all reachable pages.

Check it out!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, October 17, 2005 #

I just recently found this nice little open source tool called "floAt Mobile Agent". This cool toy enables you to manage your mobile on your computer - using your mouse and a real keyboard. You can connect a sony ericcson phone via bluetooth or irda (or wire...) and manage contacts, messages, profiles, organizer, everything. Actually, I won't have my T610 much longer, but if you've got a sony ericsson mobile, get yourself a blootooth adaptor and check this our - it's fun! floAt Mobile Agent cheers, Marc
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Thursday, September 22, 2005 #

Just found this one blogged by Yoyo: Play movie Now that's fun :)
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Last friday, Eric Jarvi blogged about the Color scheme used by the code coverage tools of Visual Studio Team System. His post made me think about code coverage another time. Beyond the fact that people tend to misunderstand the green color, there is maybe a more general misunderstanding of code coverage. The code coverage rate can easily be overestimated; Badly covered code is of course also badly tested code, well tested code sure has a good coverage rate. But well covered code is not automatically well tested. If coverage rate is at 100%, this means that every piece of code was executed at least once. So with one pass, you get good coverage, but a good test requires more passes with different sets of input. To extensively cover your code, it is necessary to test it with valid data, invalid data, and make sure to have tested border cases. This sure requires more than only one pass and relativates the coverage rate as a means for rating your tests. So maybe it's not only the green color that makes people think their covered code is "good" code - maybe it is also the overestimation of the coverage rate.
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Sunday, September 18, 2005 #

With ASP.NET 2.0, Microsoft ships a session management implementation that look like a nice solution. Sadly, however, it looks like this is not designed for reusability. It seems to be tightly coupled to ASP and not usable outside of web application. We are currently developing a component framework for .NET. Thus we need session management, and we need it for normal client-server applications, too. Sure enough, we do not want to create a new session management implementation if we don't have to. But since MS does not seem to design for reusability, it looks like we have to... Is there anyone who has found a way to use the ASP.NET session management for standard client-server component systems? I would be really inerested in this!
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, September 12, 2005 #

I have recently had the opportunity to get some experience with pair documenting. While a lot of folks are talking and writing about pair programming, not quite as much is heard about pair writing. Our recent practice made some advantages obvious:
  • The documentation quality rises enormously
  • Many inconsistencies, falsifications and typos can be omitted
  • Documenting is definitely more fun
Think about the fun aspect - I don't know any developer that loves writing doc. That's maybe the number one reason why most documentation is so poor. Making it a little more fun can help :)
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, August 08, 2005 #

Now what do you think of this?

Sun has, according to some news tickers, made a loss of about $11 Mio. Sure, that's no nice news, but hey, here's the better part:
Scott G. McNealy, Chairman of the Board of Directors and Chief Executive Officer, gets a bonus of $1,111,250. That's about 10% of the loss.. not bad, isn't it? The full board of directors gets bonus payments worth $1,889,563. And the funniest thing about this is that they actually missed their own goals...

I guess I must become a Sun manager in my next life.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

So eventually, I've a Geekswithblogs bolg, too. First of all, many thank to Jeff for this one. I got my account surprisingly fast! Now I am quite curious about how this thing is going to develop. (Maybe I'm the only one, but....) stay tuned, the "real stuff" is to come...
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati