NHibernate presentations at DNUG Bern

September 2nd, 2010 Patrick No comments

dnugbe

I hold in august two presentations at the .Net User Group Bern together with René Leupold.  In both presentations the topic was object relational mapping in the .Net world. So we showed Microsoft Entity Framework 4.0 and NHibernate. My part was NHibernate and Rene showed EF.

In the first presentation which was on 16th August 2010, we presented the following stuff:

  • Introduction into ORM
  • Theory (ORM impedance mismatch, persistence ignorance and ORM isn’t a silver bullet)
  • Approaches how to map entities (top down, middle out, bottom up and meet in the middle)
  • Introduction into Entity framework (history, vote of no confidence, supported approaches)
  • Short demo of Entity framework (configuration, hello world sample)
  • Introduction into NHibernate (history, multiple options to do things, supported approaches)
  • Short demo of NHibernate (configuration, hello world sample)
  • Mappings and short demos of them (1:m, m:n, 1:1, self references, 1 class and multiple tables, 1 table and multiple classes, inheritance with TPH, TPT and TPC)

You can find the slides here.

In the second presentation which was on 23th August 2010, we presented the following topics:

  • Queries (I showed HQL, Criteria API with QBC and QBE, NativeSQL, Named Queries and QueryOver in NHibernate 3.0)
  • Lazy and Eager Loading
  • Debugging and Profiling (also with NHProf from Ayende)
  • Optimizations

We had more stuff for the second session like Concurrency, Auditing, Validation and Caching, but we hadn’t the time to show all these things. You can find the slides from the second session here.

The samples of both sessions are also available. If you use them commercially or for other public activities, please mention the authors (NHibernate: Patrick Weibel, EF: René Leupold). The samples for NHibernate could be found here and those for EF you find here.

  • Share/Bookmark
Categories: .Net, Private Tags:

ConfORM – Another NHibernate mapping possibility

September 1st, 2010 Patrick 1 comment

I recently hold two presentations at the .Net User Group Bern (DNUG) with René Leupold about object relational mapping in the .Net world. We showed Entity Framework 4.0 and NHibernate. My part was NHibernate. You could download the slides and samples from the DNUG website.

In the two presentations I showed the mapping possibilities with hbm.xml files, attributes and Fluent NHibernate. In a previous blog post I already showed those possibilities.ConfOrmBigTransparent

During the preparations I hadn’t time to try a new way to map your entities to the database. This new way is offered by the framework ConfORM, created by one of the contributors of NHibernate Fabio Maulo.

In a previous post I showed the other possibilities how you can map your entities. In this post I show you the most simplest way I found to map the entities with ConfORM. I used for this example the version 1.0.2 (Alpha 2) of ConfORM and the version 3.0.0 Alpha 2 of NHibernate. The current version of ConfORM is available here.

Domain

The domain for this sample is quite simple. It is a one to many mapping between Order and its OrderItems. The associations is bidirectional. Below you see the class diagram of the two classes:

ClassDiagram

Database

The following ERD show the two tables Order and OrderItem in the database. Between the two tables exists a foreign key constraint. None of the fields are nullable.

database

Configuration

First, we need to declare the connection string, so that we could connect to the database. I could do it in the code, but even for a such simple example it is too dirty for me. So I added an application configuration file (app.config) and added following lines:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<connectionStrings>
		<add name="default" connectionString="Server=localhost;database=ORMSamples;Integrated Security=SSPI;"/>
	</connectionStrings>
</configuration>

Now I have a connectionstring named “default” which points to my local database ORMSamples.

When you are familiar with NHibernate, you know that you have to have a place where your session factory lives and will be created. For this purpose I normally create a class called PersistenceManager. The field factory, the property Factory and the method OpenSession are the code I would create also when I map my entities with hbm.xml files or with Fluent NHibernate or with attributes.

Where it starts to be different is the CreateConfiguration method. In this method I could create the configuration part by code. This fluent API to create a configuration is called Loquacious. Normally I would declare all this stuff in the application configuration file.

I think for a such simple application it is OK to do it like that, but I prefer the way over the application configuration file. The reason for that is, that I could configure my application for each scenario (depends on database product, etc.).

namespace ORMSamples.ConfORM.Utils
{
	public class PersistenceManager
	{
		private static ISessionFactory factory;

		private static ISessionFactory Factory
		{
			get
			{
				if(factory == null)
				{
					Configuration config = CreateConfiguration();
					factory = config.BuildSessionFactory();
				}

				return factory;
			}
		}

		public static ISession OpenSession()
		{
			return Factory.OpenSession();
		}

		private static Configuration CreateConfiguration()
		{
			var configure = new Configuration();
			configure.SessionFactoryName("Demo");

			configure.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>());
			configure.DataBaseIntegration(db =>
			{
				db.Dialect<MsSql2008Dialect>();
				db.Driver<SqlClientDriver>();
				db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
				db.ConnectionString = ConfigurationManager.ConnectionStrings["default"].ConnectionString;
				db.LogSqlInConsole = true;
				db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
			});

			configure.AddDeserializedMapping(GetMapping(), "ORMSamples_ConfORM");

			return configure;
		}

		private static HbmMapping GetMapping()
		{
			return null;
		}
	}
}

Yet I didn’t map one entity but there is an empty method GetMapping. In this method we will program our mapping in the next section.

Mapping

Below you see the completed class PersistenceManager. The implementation was created based on the example in the source code of ConfORM. The main method here is the GetMapping method. It implements a template method pattern to create the mapping.

Very important for the mapping is the method DomainDefinition. There you define your domain what means you declare all root entities. In our case it means that we have to add Order and OrderItem as root entities. For this purpose you have to call TablePerClass on the instance of the ObjectRelationalMapper class for each entity (or call it once for a collection of entities).

The patterns in ConfORM I will leave here out and come directly to the Customize method. In this method I implemented again a template method pattern. In the method CustomizeRelations I define all specialties of my entities, in the method CustomizeTables I define the DB-Schemas and finally in the method CustomizeColumns I define that the properties are all not nullable.

namespace ORMSamples.ConfORM.Utils
{
	public class PersistenceManager
	{
		private static ISessionFactory factory;

		private static ISessionFactory Factory {...}

		public static ISession OpenSession() {...}

		private static Configuration CreateConfiguration() {...}

		private static HbmMapping GetMapping()
		{
			ObjectRelationalMapper orm = new ObjectRelationalMapper();
			orm.Patterns.PoidStrategies.Add(new NativePoidPattern());
			Mapper mapper = new Mapper(orm);

			var entities = new List<Type>();

			DomainDefinition(orm);
			RegisterPatterns(mapper, orm);
			Customize(mapper);

			entities.AddRange(GetEntities());

			return mapper.CompileMappingFor(entities);
		}

		private static void DomainDefinition(ObjectRelationalMapper orm)
		{
			orm.TablePerClass(GetEntities());
		}

		private static void RegisterPatterns(Mapper mapper, IDomainInspector domainInspector)
		{
		}

		private static void Customize(Mapper mapper)
		{
			CustomizeRelations(mapper);
			CustomizeTables(mapper);
			CustomizeColumns(mapper);
		}

		private static void CustomizeRelations(Mapper mapper)
		{
			mapper.Class<Order>(cm =>
			{
				cm.Id(o => o.Id, im => im.Generator(Generators.Identity));
				cm.Bag(
					o => o.Items,
					x =>
						{
							x.Key(k => k.Column("OrderId"));
							x.Lazy(CollectionLazy.NoLazy);
						},
					x => { });
			});
			mapper.Class<OrderItem>(cm =>
			{
				cm.Id(o => o.Id, im => im.Generator(Generators.Identity));
				cm.ManyToOne(
					x => x.Order,
					m =>
						{
							m.Column("OrderId");
							m.Fetch(FetchMode.Join);
							m.NotNullable(true);
						});
			});
		}

		private static void CustomizeTables(Mapper mapper)
		{
			mapper.Class<Order>(cm => cm.Schema("OneToMany"));
			mapper.Class<OrderItem>(cm => cm.Schema("OneToMany"));
		}

		private static void CustomizeColumns(Mapper mapper)
		{
			mapper.Class<Order>(
				cm =>
					{
						cm.Property(x => x.OrderNumber, m => m.NotNullable(true));
						cm.Property(x => x.CompanyName, m => m.NotNullable(true));
						cm.Property(x => x.Street, m => m.NotNullable(true));
						cm.Property(x => x.PostalCode, m => m.NotNullable(true));
						cm.Property(x => x.City, m => m.NotNullable(true));
					});
			mapper.Class<OrderItem>(
				cm =>
				{
					cm.Property(x => x.Quantity, m => m.NotNullable(true));
					cm.Property(x => x.ProductId, m => m.NotNullable(true));
				});
		}

		private static IEnumerable<Type> GetEntities()
		{
			return typeof(Order).Assembly.GetTypes().Where(t => t.Namespace == typeof(Order).Namespace);
		}
	}
}

How to test it

Normally I would start with the test first, but this post is about ConfORM and not about TDD or the test first approach. To test our simple example is quite easy: You could create some CRUD-Tests. To not clutter this blog post I publish here just a Create-Test. As you can see, it’s normal NHibernate code and the whole mapping is encapsulated in the PersistenceManager class.

namespace ORMSamples.ConfORM.Test.OneToMany
{
	[TestFixture]
	public class OneToManyCRUDTest
	{
		private Order order;
		private OrderItem orderitem;

		[SetUp]
		public void SetUp()
		{
			order = new Order();
			orderitem = new OrderItem();
		}

		[TearDown]
		public void TearDown()
		{
			using(ISession session = PersistenceManager.OpenSession())
			using(ITransaction tx = session.BeginTransaction())
			{
				session.Delete(order);
				tx.Commit();
			}
		}

		[Test]
		public void TestCreate()
		{
			// Arrange
			order.OrderNumber = "12345";
			order.CompanyName = "Test Company";
			order.Street = "Hauptstrasse 1";
			order.PostalCode = "1234";
			order.City = "Zürich";
			orderitem.Order = order;
			order.Items.Add(orderitem);
			orderitem.ProductId = 234;
			orderitem.Quantity = 1;

			// Act
			using(ISession session = PersistenceManager.OpenSession())
			using(ITransaction tx = session.BeginTransaction())
			{
				session.Save(order);
				tx.Commit();
			}

			// Assert
			Assert.AreNotEqual(0, order.Id);
			Assert.AreNotEqual(0, orderitem.Id);
		}
	}
}

Conclusion

The first impression of ConfORM was that it seemed to me more complicated than Fluent NHibernate. But after a while I was able to work with. I’m sure, that I didn’t understand all implemented ideas, but the framework still in alpha so I have time to learn them.

ConfORM doesn’t say you how to manage the code where you specify your mappings like Fluent NHibernate. So, you have to be cautious not to code all your mappings in one class (as I did with the PersistenceManager). In this point I find the more stricter way of Fluent NHibernate a bit better.

The owner and contributor of ConfORM, Fabio Maulo, has react very fast as I asked him to implement the missing fetch attribute for collections. If you have questions about ConfORM, you can ask him directly via twitter or the community via the Google user group. ConfORM is definitively an interesting alternative for mapping entities in a fluent way.

  • Share/Bookmark

Subversion daemon Init script

July 21st, 2010 Patrick No comments

Unfortunately I didn’t find a simple good daemon Init script for a debian Linux server where I want to start the subversion server svnserve automatically on start-up. So after a little bit searching on the internet and adapting the found resources (here or here), I got my Init script svnserve under /etc/init.d:

#!/bin/sh
#
# start/stop subversion daemon.
EXECUTABLE=/usr/bin/svnserve

# Test exist:ence of the executable
test -f $EXECUTABLE || exit 0

# Command line options for starting the service
OPTIONS='-d -r /var/svn'

. /lib/lsb/init-functions

case $1 in
start)
log_daemon_msg "Starting subversion daemon: $EXECUTABLE $OPTIONS"
start-stop-daemon -vo -x $EXECUTABLE -S -- $OPTIONS
log_end_msg $?
;;

stop)
log_daemon_msg "Stopping subversion daemon: $EXECUTABLE $OPTIONS"
start-stop-daemon -K -qo -x $EXECUTABLE
log_end_msg $?
;;

force-reload)
$0 restart
;;

restart)
$0 stop
$0 start
;;

*)
log_daemon_msg "Usage: /etc/init.d/svnserve {start|stop|restart}"
exit 1
;;
esac

exit 0

After you created that script (be sure that the file is executable), you have to add the script to the boot sequence:

update-rc.d svnserve defaults

If you see errors or improvements, feel free to add a comment.

  • Share/Bookmark
Categories: Private Tags:

Round-up of a data centric architecture

April 11th, 2010 Patrick No comments

In my last big project we had to use a data centric architecture. There was a learning curve which architecture was the most appropriate one. The result is visible in the picture bellow:

Architektur

Lets explaining the diagram. The data (or state) is managed by the database layer and the common layer which contains the .Net class DataSet and the DataTables (logic representation of the physical table in the database). This architecture makes use of the patterns Table Module for domain logic and Table Data Gateway for data access logic.

There is no need for DTOs, the state is loaded by the data access layer into the DataSet which is transported through the upper layers. That means, that all layers (except the database layer) know the common layer. Instead of using the DataSet, you could realize that also with POJOs. But that leads in a data centric approach to an anemic domain model.

The domain layer contains the core business logic (domain logic). When you use a data centric architecture, then you couldn’t program in a pure OO-way. All methods have to have a pointer to the data. In this architecture you have possibility to solve that problem: One pointer to the data-structure (here DataSet) and another to the DataRow by a key (for example the primary key). The other possibility is, that you get a DataRow once and pass it around. The problem with this solution is, that you could get a mess with several DataSets.

One important lesson that was learned, was the need of a service layer (Service Layer pattern) which we called use case layer. This layer contains the services, here Controller called. A Controller represents a use case, for example an activity in a workflow process or a simple CRUD window. The responsibility of a Controller is to control and to coordinate what happen in a use case:

  • Prepare initial data structure, load data for combo boxes
  • Coordinates load or validation of data for additional AJAX calls
  • Coordinates the validation of the data structure
  • Delegate the persistence of the data structure

The layers report data source, workflow and remoting (contains facades which realize the Remote Facade pattern) are just technical layers. They don’t contain any relevant logic. They just delegate to the use case layer.

Finally, the two layers report and web represent the user interface. The report layer talks only with the report data source layer and the common layer. The web layer talks only with the remoting and common layer and asynchronous with the workflow layer. As web layer technology we used ASP.Net Web Forms.

Using silos

We used the term silo to define what you have to do to realize a use case. There were two major use cases: Simple CRUD dialog or a workflow activity (which have also a dialog).

The silo for a simple CRUD dialog contains: Code behind, View, Document, Facade Interface, Facade, Use Case Interface and a Controller.

The silo for a workflow activity contains: Code behind, View, Document Facade Interface, Facade, WFModule, Use Case Interface and a Controller.

The big advantage of a silo is, that it is clear what you have to do and where what kind of logic has to be. It is also clear that you shouldn’t reference classes of an other silo. This rule helps to minimize the side effects.

But there is also a disadvantage: A silo generate boilerplate code (Interfaces, WFModule, Facade). This leads to the anti pattern accidental complexity. To reduce this problem, you could use wizards in your IDE or some code generation tools.

Make clear decisions where reuse should happen

The use of silo arise the question where the reuse of logic happens. This was an other important lesson learned. It is important that it is clear where the reuse has to happen. In this architecture it happens in the domain layer with the methods of the BusinessObject and TableModule. Those methods are driven by the domain and have specific names, what simplifies the reuse.

Conclusion

After understanding the architecture, we were quite productive. But I’m still a fan of simple and clean OO architectures, for several reasons: avoid accidental complexity, encapsulation, information hiding or inheritance. Most of those reasons are a problem with this architecture.

A nice side effect of this architecture is a good support for testability. You could set up every state what you want because there is no encapsulation. The problem of dependencies between classes still has to be solve with dependency injection and a mocking framework.

If you use a technical environment which gives you strong instrument for a data centric architecture you should consider to use them. Important for a data centric architecture is that you define rules where you place your logic and where the reuse happens.

  • Share/Bookmark
Categories: Software architecture Tags:

Branching practices

April 6th, 2010 Patrick No comments

In an environment where several developers work at the same code base or several features have to be implemented, then branching will be a topic. I was asked to create a branching guide for my current employer which use TFS as source code repository.

Motivation

In our projects I found the following problems:

  • When the developers want to release a new version, not every feature was finished. So they had to deliver unfinished features. To solve that problem, they need to disable the unfinished features by configuration.
  • Some features which they had to implement were breaking features. In a such case, they were blocked to deliver new fixes or little features.
  • Sometimes they had to produce a hot-fix for the version which was in production. In a such scenario, they had to take manually the labeled version from the repository and build a hot-fix. After that, they had to copy the fixed code into the current code base.

Branching Guide

For those three scenarios branching could minimize the impact. So I described in the branching guide the following patterns to solve our problems:

  • Feature-Branch (and Team-Branch)
  • Developer-Versions
  • Production-Branch
  • Feature-Freeze

image

Feature-Branch

A Feature-Branch is a branch which is created always from the Main-Branch. It’s important to choose the right granularity for a feature. A worst-case-scenario is when you split a feature over several Feature-Branches, so that they become dependent on each other. A good granularity is for example a module or a workflow (several GUIs), something which is self-contained.

With Feature-Branches you have the possibility the use the cherry-picking method. That means, that before you release a new version, you choose by some quality gates (code coverage, code review, documentation, etc.) which Feature-Branches you want to merge back to the Main-Branch.

A special version of a Feature-Branch is the Team-Branch (not visible in the picture). A Team-Branch is a Feature-Branch which will be reused after a completed feature (and reverse integration to the Main-Branch). A Team-Branch will reduce the number of branches and it is assign exactly to one team or team member. It is also important, that on a Team-Branch it is allowed to implement exactly one feature at a time.

Developer-Version

The Developer-Version (in the picture the labels 2.1.2016.1 or 2.1.2016.2) are needed, when you have to create a version of your application or component to deliver it to another team. We had some dependencies of components and for breaking features, all of them were influenced. So we created a Feature-Branch in each component and published for each a Developer-Version. The dependent component could reference that Developer-Version in the corresponding Feature-Branch. A Developer-Version is just for internal use, it isn’t allowed to deliver it to the customer.

Production Branch

The Production-Branch is the representation of the actual delivered version of an application or component. In our situation, it wasn’t possible that there were several versions in production. So, we didn’t need for each release a separate branch, we could reuse a branch – the production branch.

There a two approaches how to refresh the Production-Branch: After the end of the Feature-Freeze, when the new version was shipped. The other possibility is before you create the first hot-fix (refresh with the help of the labeled version).

Feature-Freeze

When you have to create a new version, you have to decide what you will or could deliver. After you merged all good Feature-Branches then the Feature-Freeze begins. During the Feature-Freeze it isn’t allowed to add any features, but it’s allowed to fix the current version. Before the Feature-Freeze ends, you have to release your current version to ship.

When the Feature-Freeze takes a long time, then you have to create Feature-Branches to continue the development for the next version.

Branching and Continuous Integration

Branching and Continuous Integration aren’t the best friends. With Branching you want to isolate the features from each other, but you pay it when you have to merge. Merging is a manual integration of two versions, and it isn’t always fun to do it.

With Continuous Integration you want to prevent a big bang integration. You want to give the developers as early as possible feedback, that the current code is breaking or not.

In our situation, we had Continuous Integration for the Main-Branch, but not for the other branches. I would recommend to add Continuous Integration for the other branches too if they take a longer time. I would recommend also to forward integrate several times to avoid a difficult merge at the end.

Further Reading

Microsoft Branching Guide III

Feature Branch by Martin Fowler

Software Development Stages

  • Share/Bookmark