donderdag 30 maart 2006

Low key portraits with a Hasselblad

The past few weeks, I (and my fellow photography students) have been playing with Hasselblad camera's in the studio.

This is a low key portrait that one of my collegue students took from me.





Unfortunately, I was not able to scan the entire picture (it is to big for my scanner), so that I cannot present it here in its original and typical square Hasselblad format.

I also took some very nice shots from other persons, but I'm not going to post them here (yet), since I do not have the permission of those persons to do so.

I really like those Hasselblad camera's. They're great to work with and provide great quality. I even think of buying one (a 2nd hand, because these things are expensive...)

donderdag 9 maart 2006

NHibernate: where's the productivity ?

I've been playing around with NHibernate the past few days, and I've encountered a rather strange bug...

I wanted to perform a rather simple HQL query. I wanted to know the total value of the Orders that were placed by a Customer.
So, I thought that this simple HQL query would do the job:

IQuery q = theSession.CreateQuery("select sum(ol.Price * ol.NumberOfItems)
from OrderLine ol");

However, this didn't work...
This query did work however:

IQuery q = theSession.CreateQuery("select sum(ol.Price) from OrderLine ol")


It appeared that the query (the one with the multiplication in the sum function) that was sent to the database looked like this:

select sum(orderline0_.NumberOfItems*orderline0_.ItemPrice) as x0_0_
from tblOrderLine orderline0_

while NHibernate was then trying to access a result-column that was called x1_0_
This will offcourse not work, since the field has been given the alias x0_0_

After some searching, I've found out that this was a bug that also existed in Hibernate, but has been fixed in Hibernate 3.0.

So, I had to look for an alternative.
The idea came up that I could retrieve all the orderlines that belong to a specific Customer, and then, do the calculation myself.
So, I came up with this HQL query:

IQuery q = theSession.CreateQuery ("from OrderLine ol " +
" inner join Order inner join Customer " +
" where Customer.Id = :custId");

This didn't work as well... An exception was thrown saying that the BY keyword was expected after a GROUP or ORDER. However, I didn't use any group by or order by statements ? Then, I've noticed that I've a class that's called Order, so maybe I had to escape the classname.
However, I couldn't find how to do that (if it is possible), so I've rewritten the query to something like this:

IQuery q = theSession.CreateQuery ("select ol " +
" from OrderLine ol, Order o, Customer c" +
" where ol.Owner = o and o.Owner = c " +
" and c.Id = :custId");

This didn't work as well...
The exception now said:
Could not resolve property:Id of Customer
I found this very strange, since this class has an Id property.
After some research, I found out that the Id did not appear in my hibernate mapping file indeed.
This is, because the Id is used as the 'id' in my mapping file, and, since the Id property is read-only in my class, I use a field access method to set this field. This is specified in my hbm mapping file like this:

<class name="NamespaceName.Customer, NamespaceName" table="tblCustomer">
<id name="id" access="field" column="Id"... >
...


So, what should I do next ? I didn't want to make the Id property of my Customer clas s writable.

I tried to add the Id property to my Customer mapping file, without touching the 'id' element.
So, I've added the Id property to my mapping file, but, since I've introduced the same database column twice, I had to use some attributes:

<class name="NamespaceName.Customer, NamespaceName" table="tblCustomer">
<id name="id" access="field" column="Id"... >
...
<property name="Id" update="false" insert="false">
...


Now I tried to rerun my query. However, retrieving a Customer was already a problem. I received an exception that said that the property value of the Id property could not be set via reflection. Damn.
I really don't want that somebody can set the Id of a Customer via the property...

Luckely, .NET 2.0 came to the rescue. In .NET 2.0, you can define different access-modifiers on your property getter and setter. So, my Customer class looked like this :

public class Customer
{
private int id;

public int Id
{
get { return id; }
}
}

I've changed this to

public class Customer
{
private int id;

public int Id
{
get { return id; }
private set { id = value; }
}
}


And this finally did the trick...

I've spent something like 2 hours in getting something simple like this to work in NHibernate. With a self-written Data Access Layer, this would have taken me something about 10 minutes I guess, to implement this functionality.
Conclusion: there's a lot of work to be done on NHibernate before I will really call it 'productive'. However, it is a promising project though.

For more information about my quest, I refer to a topic I've opened regarding this issue on the NHibernate support forum.

maandag 6 maart 2006

Troubles with Visual Sourcesafe, looking for alternatives

Today, I've encountered some rather unpleasant moments with Visual Sourcesafe. Around 4 o'clock, it appeared that my VSS repository was corrupt. :(
Trying to restore the latest backup didn't succeed as well, since there was a problem with that tape. :(

This means I had to use the backup of last thursday... Luckely, after some extra work, I've been able to restore most of my work.

However, I do not want to experience these problems again, so, just like Sam Gentile, I'm going to ditch VSS, and look for an alternative.

At this moment, I've 2 options in my mind:

  • SubVersion

  • Sourcegear's Vault


Some time ago, I've downloaded a trial version of Vault, and it looked ok to me. However, I've heard that it doesn't integrate very well in VS.NET (haven't tried that yet).
On the other hand, we have Subversion, however, I haven't worked with it before.

Anybody who has experience with one of these 2 systems and wants to share his/her opinion ?

zondag 5 maart 2006

Formula One: The new season is coming...

At last, after a long winter of F1-less Sundays, the new Formula 1 season will start next sunday.
I find it always interesting to see during the first race of the year which teams have done their home-work, and will be the teams to beat during the season.
I bet that, for the 2006 season, Renault and Honda will be the favorites for the World Championship with Ferrari and McLaren on their heels.

Who will be world champion ? Will Alonso extend his title, or is Schumacher able to fight back ? Can Raikonnen, who has been close to catch the title last year and in 2003, finally clinch the championship ?
However, I think that Jenson Button also has a chance to win some races this year...

All questions that will be answered during the next months, and the first race in Bahrein should already give a strong indication of who holds the best cards.

Anyway, I'll be supportering for Kimi Raikonnen and Jacques Villeneuve. I just like the driving style of these 2 guys.
I hope that it will be an interesting season, with a lot of exciting duels on the track.


To get into the F1-mood, here (18mb) is a video-clip of one of the most exciting duels in F1 history.
This video shows the last 3 laps of the 1979 French Grand Prix which was held in Dijon. René Arnoux and Gilles Villeneuve are contending for 2nd place. René Arnoux is driving a Renault Turbo (with a defect Turbo), while Villeneuve is driving an atmospherical Ferrari with worn out tires. (You'll see the reason for those worn out tires...). The commentary is from the legendary Murray Walker.

woensdag 1 maart 2006

It's been a while...

It's been a while since I've made a post on my blog. I'm currently busy reading the book Agile Software Development and I'm also playing with NHibernate a little bit.
I am thinking of creating a little tutorial / Quickstart about NHibernate and post it here, but I'm not sure yet. It is a lot of work, and takes some time... :)

zaterdag 18 februari 2006

A 'problem' with custom configSections in .NET 2.0

Yesterday evening, I was trying to port a simple .NET 1.1 test project of mine to .NET 2.0.
This project contained an App.Config file that contains a custom configuration section like this:
<configuration>
<configSections>
<section name="test"
type="System.Configuration.NameValueSectionHandler"/>
</configSections>
<test>
<add key="xx" value="yy"/>
</test>
</configuration>


When I compiled my project, I got the following error message from VS.NET:

Could not find schema information for the element test
Could not find schema information for the element add
Could not find schema information for the element key
Could not find schema information for the element value

I was really surprised... This just worked in .NET 1.1, why shouldn't it work in .NET 2.0 ?
I spent a lot of time searching on Google, newsgroups, etc... for more information about this error and how to solve it, but I haven't found any clue.

This morning, I restarted my quest, and I was able to solve the problem.
Apparently, I had a syntax error somewhere in my code. In the configuration file, there was nothing wrong. Once this syntax error was solved, VS.NET didn't complain anymore.
I tried the same thing in my .NET 1.1 project: I added a syntax error in my code, and compiled. The compiler complained about the syntax error, but not about the configuration file (which is good, because the config file is correct).

This is very frustrating. Why is VS.NET 2005 complaining about something in the configuration file, while the configuration file is just correct ?
On top of it, this 'configuration file error' appears as the first error in my error-list.

I really lost a lot of time due to this strange behaviour of VS.NET; why is VS.NET 2005 behaving like that, which is incorrect IMHO, while VS.NET 2003 is acting like it should.
This error is very confusing and it can really take your productivity down.

Update: I've been playing with configuration-settings in .NET 2.0 again, and again, I came across this annoying error. I've made 2 comments on this article that should provide a way to fix this.

dinsdag 14 februari 2006

Domain Driven Design / Entity (Yourdon-Chen) approach

The last few months, I've been reading a lot in the book Domain Driven Design by Eric Evans.
The book preaches really useable things such as 'the separation of concerns', and 'expressive domain models'. These are practices where I try to strive to, and the more I read in the book, the more this 'Domain Driven paradigm' appears to me as 'the Holy Grail' in software developmment.

However, when you want to turn theory into practice, you sometimes run into problems...

For instance, suppose you have a simple domain model for some shop. In this domain model, you'd have a Customer entity, and this Customer has Orders. An Order consists of one ore more OrderLines.
Suppose we should treat a Customer who ordered for more then 1000€ in the last 6 months as a 'Gold Customer'.

In a Domain Driven Design, it would feel natural to add a member to the Customer which tests this condition, and it could look like this:
public class Customer
{
...
public bool IsGoldCustomer()
{
decimal total = 0;

foreach( Order o in _orders )
{
if( o.OrderDate >= sixMonthsAgo )
{
total += o.TotalOrderValue;
}
}

return ( total > 1000 );
}
}


As you can imagine, this will not be very performant. First of all, this code requires us to traverse over the entire OrderCollection of that customer.
It could also be that the TotalOrderValue property is also a calculated value.
This means that, for every Order who's orderdate falls within the last 6 months, we'll have to retrieve the OrderLines (suppose that the OrderLines are lazy-loaded) in order to be able to determine the TotalOrderValue of that Order.
As you can see, this means that we'll have to do a lot of query-ing and we also have to retrieve a lot of records out of the database and load them into memory... For just such a simple check...
This is not really a best practice.

Luckely, our database is able to determine the amount of placed orders in the last 6 months for a specific customer in a much faster way, and without the need of loading a lot of objects into memory.
By using a Specification pattern, we can make use of the power that our database offers, and still have the logic encapsulated into the domain:

public class CustomerGoldStatusSpecification : CustomerSpecification
{
public bool IsSatisfied( Customer c )
{
decimal total =
customerRepository.
GetTotalOrderValueForCustomerInPeriod(c.Id, sixMonthsAgo, today);

return (total > 1000);
}
}


In this way, the logic is still encapsulated in the domain model, since the CustomerGoldSpecification class is a part of the domain, and, we also make use of the power of our database; the specification uses a method on the Customer Repository which queries the database for the value that we want.

Nice. :)

However....

If we take this logic out of our 'entity' classes, then what difference does this 'Domain Driven' approach make with the Yourdon/Chen entity approach ?
If we take the 'complex' logic and behaviour out of our domain classes, what else is left but some dumb entities that are nothing more then a data-holder, while all our logic is in specifications / managers ?

One could ofcourse say that the Specification class can be made internal, and the Customer should use this specification class like this:
public class Customer
{
public bool IsGoldCustomer()
{
CustomerGoldStatusSpecification spec =
new CustomerGoldStatusSpecification();

return spec.IsSatisfied (this);
}
}

(You can offcourse also directly access the repository from this Customer class)

Am I exagerating about this ? Is the situation I've described here, and the solution a good solution ? Is there still a difference between this approach and the Entity/Yourdon approach ?
I'd like to hear your comments and opinions.

vrijdag 10 februari 2006

Better performance when loading a typed dataset.

At work, we had a little performance problem when we wanted to fill a rather large typed dataset that had a number of constraints defined.

Setting the EnforceConstraints property of the dataset to false before filling up the dataset, and setting it to true afterwards, resulted in an immense performance boost.
Without setting this property to false, it took minutes to load the dataset. When we made use of this property, it only took a second or two.

donderdag 2 februari 2006

Business Objects Framework - Part 3: Lazy Loading

This is the 3rd part of my 'Business Objects' serie. In this article, I'll discuss the LazyLoadCollection. (Part 1 and 2 can be found here and here.

Introduction


Suppose you have a class Customer. This Customer class has collection of 'Orders'. Each Order contains a collection of OrderLines.
Now, if you retrieve one or more Customers out of the database, it is maybe not such a good idea that you retrieve all the Orders and OrderLines with it. It is probable that the user is not interested in all the orders or all the orderlines of each customer that you have retrieved.
If you do this, it means that a lot of objects will be loaded into memory; objects you might not need.
Therefore, it is sometimes a good idea to load this information only when you need it. In the scenario I've described here, I think it is a good idea that, when you load a Customer out of the database you should also get his Orders.
In most cases, you want to have an overview of the Orders of a Customer. This means that you will need the Orders of the Customer in most of the cases.
However, you're only interested in the OrderLines of an Order, once you decide to view the details of an Order. Here, you should only retrieve the OrderLines out of the database, when they're needed. This is where the Lazy Loading comes in.

The LazyBusinessObjectCollection class


The Lazy Load functionality must be transparant to the user of our Order class. This means that, the user must be able to Add, Remove and see the OrderLines of an Order just like he/she can do with a normal collection class.
Even if the OrderLines of an Order have not been loaded yet, it must be possible that OrderLines are being added.

So, how can we do that ? The Proxy Design Pattern offers us a way to do that.
Instead of giving the Order class a 'real collection' as a member to hold it's orderlines, we will give it a proxy object that acts as a collection.

This means that we must create a class that has all functionality of a collection. The easy way to do so, is to create a class that is a wrapper around a Collection object, and acts as a Collection as well.
We can create a class that is a wrapper around the BusinessObjectCollection class that we've created earlier. This wrapper class must also implement the ICollection interface so that it can act as a collection. We also want Undo-support, so this class must implement our IUndoable interface as well.

The skeleton of our LazyBusinessObjectCollection will look like this:
[Serializable]
public class LazyBusinessObjectCollection<T> : IUndoable, ICollection<T>
where T : BusinessObject
{
}


Earlier, I said that the LazyBusinessObjectCollection class would be a wrapper around the BusinessObjectCollection class. This means that the LazyBusinessObjectCollection class should have a member of type BusinessObjectCollection.
[Serializable]
public class LazyBusinessObjectCollection<T> : IUndoable, ICollection<T>
where T : BusinessObject
{
private BusinessObjectCollection _collection = null;

private BusinessObjectCollection CollectionObj
{
if( _collection == null )
{
// initialize and load the items.
}
return _collection;
}

}

I've also created a property that accesses the BusinessObjectCollection member. This property should be used everytime we access our BusinessObjectCollection from within the LazyBusinessObjectCollection class, since this property will take care that the BusinessObjectCollection is loaded if this is necessary.

To be able to populate the collection, we need something that can loads the data for us. We want to decouple the LazyBusinessObjectCollection from the code that retrieves the items for us, since, this 'data retrieval code' will be most likely in some kind of Data Access Layer.

So, I decided to create an interface ILazyLoader
This interface looks like this:
public interface ILazyLoader<T> where T : BusinessObject
{
List<T> GetObjects();
}


This interface defines only one method that gives us a list of BusinessObjects. This means that the class that implements this interface is responsible for retrieving and returning the BusinessObjects.

So, we can give an ILazyLoader to our LazyBusinessCollection class. This ILazyLoader can be provided by the constructor of the LazyBusinessObjectsCollection class, and the property that we've created earlier, can access the GetObjects method which will give the Objects that the collection must contain:

[Serializable]
public class LazyBusinessObjectCollection<T> : IUndoable, ICollection<T>
where T : BusinessObject
{
private BusinessObjectCollection _collection = null;
private ILazyLoader<T> _loader;

private BusinessObjectCollection CollectionObj
{
if( _collection == null )
{
_collection = new BusinessObjectCollection<T> ();

foreach( T item in _loader.GetObjects () )
{
_collection.Add (item);
}
}
return _collection;
}

public BusinessObjectCollection( ILazyLoader<T> loader )
{
if( loader == null )
{
throw new ArgumentException ("You must provide an ILazyLoader",
"loader");
}
_loader = loader;
}

}


Pretty simple huh ?

Now, an ILazyLoader can look like this:
public OrderLinesLoader : ILazyLoader<OrderLine>
{
private int _orderId;

public OrderLinesLoader( int orderId )
{
_orderId = orderId;
}

public List<OrderLine> GetObjects()
{
// Just for simplicity of the example, normally, you should
// use parametrized queries, etc.... Consider this as pseudo-code
string sql = "SELECT * FROM orderlines " +
"WHERE OrderId = " + _orderId.ToString();

DataReader dr = dbHelper.Execute (sql);
List<OrderLine> lines = new List<OrderLine>();
while( dr.Read() )
{
OrderLine ol = CreateOrderLineFromReader (dr);
lines.Add (ol);
}

return lines;
}
}


So, the repository or factory who gives us an Order object, is responsible for initializing the OrderLines member -which is an LazyBusinessObjectsCollection of the Order class.

We still have to implement the ICollection and IUndoable interface. I will not put the implementation of the ICollection interface here to save some space; besides, it is pretty simple code: you can just delegate these calls to the BusinessObjectCollection property (note: make sure to use the property) of the LazyBusinessObjectCollection class.
The same applies to the implementation of IUndoable: just delegate the calls to the BusinessObjectCollection. However, here we can use the field instead of the property, since we only have to delegate these calls if the collection has been loaded:
public void CreateSnapshot()
{
if( _collection != null )
{
_collection.CreateSnapshot ();
}
}

...

vrijdag 27 januari 2006

Buying Books

I've bought 2 books recently.

The first one is Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Microsoft .NET Development Series).

framework design guidelines cover
This is a usefull book with some interesting tips for anyone who's interested in or is busy with designing and building frameworks. If you use FxCop, chances are that you're already familiar with most of the tips and guidelines that are in the book. Nonetheless, this book is usefull as reference-book but you can also read it from cover to cover. Most of the guidelines in the book are commented by people like Jeffrey Richter, Rico Mariani, etc... and these comments are very valuable as well.


The second book I've bought is Agile Software Development, Principles, Patterns, and Practices by Robert Martin.

agile software development cover
I haven't found time to start reading this book, but due to the reviews on Amazon and other fora, I'm expecting a lot of it! Maybe I'll post a little review on my blog about this book, after I've read it.

Again, two books that I can remove from my book whishlist

Correction: I didn't really buy the 1st book; it was rather a present. :)