My New Blog

In case anyone is wondering. I moved my blog to Medium. You can now read me at: https://medium.com/@jdp. In due course I will be moving over some of my better blog posts.


Notes On SharePoint Business Connectivity Services

The past 2 weeks I had an opportunity to develop a solution with SharePoint 2010’s Business Connectivity Services. I found working with SharePoint BCS to be a delicate process, with a few things not behaving entirely as expected. Here’s a few quick notes to help clarify some of the things that confused me most about BCS:

1.

For each BCS Entity’s Identifier, its Specific Finder must have an equivalent In Parameter. In other words, for example, if you have 2 Identifiers, then your Specific Finder method must have 2 corresponding input arguments.

2.

All the other methods have a dependency on the Entity’s Specific Finder. If you change the fields, or their Type Descriptors, of Specific Finder’s return parameter object, then you have to update the update and create methods accordingly. The principle is explained in the Implementing an Updater article on MSDN: “If there are multiple specific finders, the Updater view should be equal to, or a subset of, at least one SpecificFinder view.” I know it refers to “multiple specific finders”, but it found it to work the same whether there’s one or more specific finders.

3.

Your permissions are removed from the BCS Service Application (in Central Admin), and you get the “Access denied by Business Data Connectivity.”, when you deploy a new BCS model, after changing the methods, Type Descriptors or any other part of the model. This didn’t always seem like it happened consistently. At times, it seemed like it was removing the permission at random, even when I just updated the code of my entities or services.

4.

Make sure you activate SharePoint Server Enterprise Site Collection features for your Web Application.

5.

Whenever I modified a Creator method, and refreshed the page, I started getting strange errors on the list page, and had to recreate the List to fix it.

 

 


Playing With Gimp

Playing around with Gimp, using some awesome free ultra high quality images from gratisography.com.

Cloudy Shore

Cloudy Shore


Get Up and Running With SQL Server Express, Clojure, SQL Korma and Local Jars

Just a sweet and short little post to help others get up to speed accessing SQL Server Express 2008 with Clojure’s SQL Korma library.

Set Up SQL Server Express

I’m using SQL Server 2008 Express. To configure your DB server go to Start > All Programs > Microsoft SQL Server 2008 > Configuration Tools > SQL Server Configuration Manager. Under SQL Server Network Configuration select Protocols for SQLEXPRESS. On the panel on the right size of the screen, make sure TCP/IP is Enabled, then right click it and select Properties. Select the IP Addresses tab, and make sure you have the following settings:

  1. For IP Address 127.0.0.1
    • Active: Yes
    • Enabled: Yes
    • TCP Dynamic Ports: Make sure this entry is empty.
    • TCP Port: Make sure this entry is empty.
  2. For IPAll:
    1. TCP Dynamic Ports: Make sure this entry is empty.
    2. TCP Port: 1433

Enable SQL Server mixed mode authentication (SQL Korma doesn’t do integrated/Windows authentication). Run regedit.exe and go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQLServer. Change the LoginMode to 2, and restart the SQL Server Express service.

Okay, so we can now create SQL accounts on SQL Server Express, so let’s enable the SA account with SQLCMD:

  • sqlcmd .\SQLEXPRESS -E
  • ALTER LOGIN sa ENABLE
  • GO
  • ALTER LOGIN sa with password=’aPassword’
  • GO
  • exit

Maybe you don’t want to enable the SA account, but rather create a new non-sysadmin account, as it’s a security risk to use SA for your apps. I just used it here, as it was the shortest way to get a SQL account ;-)

Load The SQL Server JDBC Driver Into a Local Artifactory Repository

Download JFrog’s Artifactory. Go to Artifactory’s bin folder and run InstallService.bat. Then launch Artifactory with  artifactory.bat, and browse to http://localhost:8081/artifactory/webappGrab Microsoft SQL Server JDBC Driver 3.0 and load it into a local Artifactory repository with the following settings:

  • GroupId: sqljdbc4
  • ArtifactId: sqljdbc4
  • Version: 3.0

The reason we’re using Artifactory, is that Leiningen demands that all your dependencies come from a repository somewhere. Since Microsoft’s JDBC driver isn’t available on a public repository like Clojars, is make it available from a local repository. You’re other option is to directly load it into a Maven repository, but trust me, this is time consuming and something you want to avoid.

Now add your local repository to Lein’s defproject, :repositories {“ext-release-local” “http://localhost:8081/artifactory/ext-release-local/”}. You can see I chose to load sqljdbc4.jar into the ext-release-local repository. Also add the SQL Server JDBC driver as a dependency: [sqljdbc4/sqljdbc4 “3.0”]

Make a Nice Clojure SQL Korma

And finally drop SQL Korma as a dependency into your Leiningen project, and do the rest of its configuration as specified on Git Hub:  [korma “0.3.0-RC4”]. If you’re new to SQL Korma, like I am, you might think that (defentity …) will also create your database objects for you. Not so! SQL Korma doesn’t have this feature currently (version 0.3.0) – hopefully they’ll add it in future. So make sure you’re DB objects exist and that the defentity statements correctly map to them.

Sounds like a few simple steps, but I took me unnecessarily long to piece all the above together, and get to the point of accessing SQL Server Express 2008 with SQL Korma. Hopefully the above will help others to reach SQL Server and Korma Nirvana, one time!

 


Vietnam: A Journey Begins

My wife and I recently spent about 3 weeks in central Vietnam, and a few days in Singapore. As I’m absolutely hooked on history, our trip largely revolved around exploring the history of Singapore and Vietnam, and Vietnam’s in particular is vast and very colorful. Over a series of blog posts, I will be giving a personal account of the history of central Vietnam and a little bit of Singapore, that we explored during our recent holiday. As the first blog post in the series, I won’t discuss any history, rather just give a very quick overview of the things that most South Africans ask about, when we discuss our holiday in Vietnam.

From Singapore, we flew directly to Da Nang, where central Vietnam’s airport is located, then moved to Huế, and finished our holiday in Hoi An. Also keep in mind that my opinions are based on my experience in central Vietnam. The bigger cities in the far north, Hanoi and south, Ho Chi Minh, might be quite different, just like Cape Town is vastly different from Johannesburg.

Why We Chose Vietnam

It was an inspired, intuitive decision, based on the Vietnam Eyewitness Travel Guide . My only criteria for our overseas holiday, was that I’d like to visit any country with an ancient, rich and vibrant history. I think a further motivation was the exchange rate with the Rand and the fact that things are just cheaper in Vietnam (in comparison I realized South Africa isn’t such a cheap place), which made things a lot more affordable for us. I would say, on average, things are about 50% cheaper in Vietnam than in South Africa. That goes for everything from hotels to buying things at a street market. I envy how cheap a holiday in Vietnam must be for the Europeans and British.

By the way, about the Eyewitness book. It’s a wonderful little book to get inspired about the country, but don’t depend on it to get around Vietnam day-to-day. Your Swiss army knife of info, to survive in Vietnam will be the Lonely Planet’s guide on Vietnam. That book was essential to ensuring an enjoyable stay in Vietnam.

The American War in Vietnam

The first thing most people asked, is if they have yet fully recovered from the war against America. The answer to that is an unequivocal, Yes! There are absolutely no signs in any of the cities, that there has ever been a war like that in Vietnam. And I would hope so, the American war in Vietnam ended almost 40 years ago. At historic buildings and sites some signs of the war are still visible. This is hardly surprising, since these buildings are historically significant and a heritage, therefore major restorations are not really possible or allowed.

When South Africans ask me this question, I realize just how little we know about Vietnam (and the same is true of them about Africa), and that the only, outdated, knowledge South Africans have of this amazing country and people, is that which they got from western news back in the 1970s and American war movies.

Socio Economics

In short there are few rich people in Vietnam. But, there are very few people that are desperately poor. Unlike South Africa, where there is a small group of people earning a decent living, and then a massive number of people struggling to make ends meet. Something that really got my attention, was the fact that there are no informal settlements in central Vietnam. Almost everyone has a pretty little house to live in, and many even have a small holding, that they can cultivate. There are also none of those characterless, mass cloned, little matchbox houses, that the South African department of housing builds. Each little home has it’s own style. The main buildings all have the same narrow, rectangular structure, but each building has been given its own unique style by its owner. Everyone wants to sell you something, but you won’t find any beggars at the street corners.

Crime

As anyone that has spent some time with South Africans would know, we are always obsessing about crime. I’m therefore pleased to announce that Vietnam is a very safe place indeed. Safer than South Africa. We’ve heard of people’s wallets being pinched, and someone might try to scam you in a transaction at the market, but there are no armed robberies, where peoples’ expensive valuables are stolen at gun point or knife’s edge. For example, you can walk around in the street, late at night, taking pictures with your expensive camera, without fear of being robbed.

The People

The Vietnamese people seem to be a happy bunch, that’s content with life. Everyone was extremely friendly, and helpful (especially if they have something to sell you). Compared to the Singaporeans, I found the Vietnamese to let more of their emotions show. Warm, hearty laughs and smiles, frowns and even arguments in public were more frequent. Whereas the Singaporeans kept an efficient straight face most of the time. In Da Nang we even saw an older lady (I’m guessing the mother) have a massive argument with a younger lady (I’m guessing her daughter), where she later took off her sandals and started hitting the younger woman.

I got a strong sense that the average Vietnamese really doesn’t know a lot about the world outside their country’s border. From the confused expression on their faces when we answered that we’re from South Africa, it was obvious that most Vietnamese would struggle to find South Africa on a map. Most of them thought we were German (but I don’t blame them for this, I would draw the same conclusion listening to Afrikaners talking), and then some went on to tell us, after realizing that there is “Africa” in our country’s name, that we can’t be from South Africa because we are, you guessed it, white!

Twice Vietnamese were so amused to see some westerners, that they started taking photos and videos of us, right in our faces. Now that was a strange, and slightly awkward, experience.

Language

No surprises here: Vietnamese speak and write Vietnamese. However, I was expecting the English conversations to be a much bigger problem, but it turned out that most people’s English is good enough to get the job done. English of younger people from cities are actually good enough to allow a decent conversation.

You Can Also Have A Resort Holiday In Vietnam

As I’ve already mentioned, I’m completely addicted to history. So our holiday was specifically targeted at exploring, experiencing and learning about Vietnam’s history, mainly until about the 1920s (i.e. we didn’t really pay attention to the anti colonial revolution against France, and the American war in Vietnam). We visited as many historical places as we could, and often had to walk or cycle long distances in +35°C temperatures. This isn’t very comfortable, and sometimes even a little stressful to find your way, by yourself, in an unknown place. We also stayed in the heart of each city’s centre, which isn’t always the sexiest location, but it’s closest to the action.

However, if you prefer to have more of a resort type holiday, where you relax all the time and enjoy long walks on perfect white sandy beaches, then Vietnam can offer you that as well. There are a large number of modern, luxurious beach resorts to choose from, on the beach from Da Nang to Hoi An (called China Beach). So if you’re thinking of spending a holiday at a Thailand resort, maybe also check out its equivalent in Vietnam. I can highly recommend the Hoi An beachfront for those looking for a hassle free, chill holiday. Hoi An is an old town, that has been beautifully maintained and restored. So if you stay at the Hoi An beachfront, then you will get the best of both worlds – the beach resort and classic town lifestyle. Personally, I found Hoi An to be a little boring, and too much tourist focused. For example, in Hoi An’s old town, there are literally more tourists, than Vietnamese.

What An Absolutely Amazing Country

We absolutely loved Vietnam. It was one of the most profound experiences of my life. The vibrant history, people, temples, pagodas, tombs and natural beauty was unforgettable. During a three week stay we hardly scratched the surface of what Vietnam has to offer. We will definitely return in a few years (permitting finances allow it), probably to Hanoi, as that is the heart of Vietnam’s northern history.


The Other Side Of Job Creation

It astonishes me to see how everyone buys the ‘job creation’ story the state and media sells them, without considering the bigger picture. What I believe most people fail to ask is how many jobs were not created elsewhere, where there is a greater need or bigger demand. In order for new businesses to flourish, it will require reallocation of capital and people and their skills to higher yielding industries and businesses. This process is very important to the agility and livelihood of a healthy economy, where unproductive businesses close down to make way for new ones that can use the resources (capital and people) better, because they can better provide things people really want at prices they’re willing to pay. When government (and the labor unions) intervenes in this process, they waste capital by not directing resources to the most desirable industries and businesses, and applying it to their political agenda.

Consider this about private businesses: If they fail to produce in the cheapest and best possible way those things which people most need, they suffer losses and are eliminated from the economy. Other businesses who know better how to deliver the right things, at the right price, replace them. This is how inefficient businesses get eliminated from the economy, a kind of survival of the fittest. If you take the wrong decisions in business, you get punished very quickly. Do it long enough and you’re out.

Now consider this – government’s ‘capital’ comes from tax or debt. Debt is just borrowing against a government’s future income, that in turn comes from tax. Therefore, ultimately, all government’s income comes from tax. But in government’s case there is absolutely no incentive or threat to use it efficiently. Because government doesn’t get eliminated from the economy when it makes the wrong decisions about how and what to use resources for, it continues to do so at a much greater cost to the economy.

With every new ‘job creation’ project government funds, that same amount of money was previously taken away from productive businesses. Because of government’s inefficiency and misallocation, it is very likely that a lot more could have been done with the resources elsewhere, including hiring people. Also, based on what criteria does government direct resources? Yes, a lot of it is probably for the “greater good” and altruistic in nature, but an enormous part of the criteria is determined by political, emotional, subjective and selfish factors.

Another thing I find quite amusing to read is how the competition commission hunted down and punished the latest business cartel that is hurting the man on the street by manipulating prices. What is a cartel other than a type of monopoly? And we all know how much our beloved socialist government loves their state controlled monopolies: Eskom, Transnet, Telkom, PetroSA and Infraco. And what they don’t already control under these state enterprises and government departments, I’m sure they are planning to take over soon. By the sounds of it, mining and banking is next on the cards. So on the one hand government continuously seeks to end anti-competitive behavior, but on the other it’s recommended as the best solution to the nation’s problems. If there’s one thing the South African economy needs is more competition, but not only in the form of a reactive central watchdog that runs around trying to police the 3 or 5 big players in each industry. Instead we need to focus on growing the size, quality and number of entrepreneurial businesses in each industry.

At this stage government and the labour unions, are blocking the free readjustment and reallocation of resources to new businesses that can use it to better produce that what is required more. Government sucks more resources out of the economy, in the form of tax for their ‘job creation’, and labor unions force artificial labor costs on businesses. Instead of addressing the true underlying problems of our economy, government chooses to prop up ailing industries and expand the public sector. In the long run this will do very little to solve the dysfunctional structure of our economy:

1. There is poor separation of concerns between the labor unions, Cosatu, and the government. Cosatu helps the ANC government stay in power. Let’s not forget they were the big reason Zuma was elected as president, and election after election tell their members to vote for the ANC. This makes government unlikely to make the necessary labor and economic reforms, needed to pursue a true growth strategy.

2. Labour unions and the ANC government must accept, that it’s impossible to keep all current jobs, with increasing salaries, and have meaningful success in creating new businesses. Rather focus on creating new businesses, making current ones more competitive and allowing labour to adjust to the industry’s natural cost and employment structure. This means there will be jobs lost, before new ones can be created.

3. The ANC government must also realize that the free market economy is better at determining how to use resources. Resources are still wasted in a free market economy, but not for long. Expanding the public sector payroll, increasing grants, and so forth, requires more tax money, which in the end defeats their original purpose of improving living conditions.

Government Covers Up Underlying Problems by Increasing Public Sector Employment

By April 2010 the private sector (excluding agriculture) lost some 377,000 jobs from a peak in October 2008. Since then the private sector has only been able to add a 94,470 jobs, and the public sector added 106,503 or 53% of 201,000. In July 2011, private sector employment has grown 0.5% since a year before, and the public sector 3.3%. I’m just wondering what all these new government employees are doing? What are they creating that other people need? What new industries, technologies,and specialized skills are they mastering?

National departments’ wages also increased by 11.3% for the year to July 2011, and increased by more than 10% for the past 2 years. Private sector wages only increased by 7,4%. So clearly the place to work in South Africa is at government departments. This has to mean that these people are making the most important contributions to our economy, or does it? The figures seem to suggest they own specialized skills that are in high demand, because not only is the country hiring more of these people, but we’re also paying them more.

To get a picture of the SA government’s debt, I quote a sentence from the SA Reserve Bank’s Quarterly Bulletin for December 2011: “As a ratio of gross domestic product, national government’s total gross loan debt increased from 35,4 per cent to 37,3 per cent during the period under review.” So quite an innocent figure really, especially considering that America’s debt to GDP is 100% and Greece’s is 150%. But as in all things finance, it’s the trends that reveal the truth. In 2007 this figure was 27.4%, and except for 2008, has grown every year since then. Makes one wonder if South Africa isn’t maybe Africa’s version of a Greece in the making?

References


My New Chomma, Clojure

A few months ago I decided that it’s time to learn a new programming language that’s completely outside my normal frame of reference. After watching a video on InfoQ about the future of programming languages, I decided Clojure would make an interesting choice. I bought the Pragmatic Programmer book, and what can I say, we’ve been becoming good friends these days.

I think I’m taking to the functional programming paradigm, and like the idea of pure functions, without shared state. Even when I program C#, I tend to make heavy use of its closures like delegates, events, anonymous methods, and lambdas, using methods as data. Learning Clojure is quite a challenge if you’ve been conditioned by years of static typed, imperative programming.

A Very Basic Clojure Work Flow For Beginners

What I’ll describe here is a very basic workflow that will enable you to write some trivial Clojure apps and work through some of the examples you might find in books and on the web. Some of these tasks aren’t that clear reading the available material, as the authors usually skip to the more exciting parts of the language.

1. Get Counterclockwise for Eclipse
2. Create an executable command line script (in my case I called it repl.sh) to launch Clojure REPL (Read Evaluate Print Loop or Interactive Console) with the required libraries referenced in the class path (Clojure runs on the Java VM):

java -cp .:src:lib/JLine/jline-0_9_5.jar:lib/clojure-1.2.1.jar:lib/clojure-contrib.jar jline.ConsoleRunner clojure.main

This adds the necessary packages to the Java class path, and launches Clojure. JLine adds functionality to the Clojure REPL, like being able to press the up arrow to retrieve the previous command.

3. Compose your Clojure application by grouping related functions in the same namespaces. The first difference you’ll notice between Clojure, and an imperative language like Java or C#, is that it doesn’t have classes, only namespaces or packages. You define a namespace with the ns function:

(ns algorhythm.test.geometry.trigonometry-tests)

This tells Clojure to switch to that namespace, and if it doesn’t exist to create it, and to create all consecutive functions defined under it. To import another namespace to make its functions available you use the “(:use”:

(:use clojure.contrib.test-is algorhythm.geometry.trigonometry algorhythm.geometry.geometric-vector)

4. Start by writing some unit tests for your Clojure application. Or if you don’t do Test Driven Development (TDD), you can skip straight to 7, writing your actual implementation.

(ns algorhythm.test.geometry.trigonometry-tests
(:use clojure.contrib.test-is algorhythm.geometry.trigonometry algorhythm.geometry.geometric-vector))

(deftest find-longest-vertex-should-find-the-longest-vertex
(def triangle {:vertex-y (struct-map geometric-vertex :length 65 :link (struct-map vertex-link :angle 90 :vertex-name “vertex-x”)),
:vertex-x (struct-map geometric-vertex :length 99 :link (struct-map vertex-link :angle 20 :vertex-name “hypotenuse”)),
:hypotenuse (struct-map geometric-vertex :length 91 :link (struct-map vertex-link :vertex-name “vertex-y”))})

(is (= 99 (find-longest-vertex triangle))))

First create and switch to the namespace where we’re going to define our unit tests. Then we tell Clojure to reference the Clojure.contrib library, where Clojure’s unit test framework is located. You then declare your unit test functions, with (deftest …), and do assertions with (is …).

5. Launch Clojure’s REPL from terminal and load your unit test .clj files with (load-file …).

jacquesd@ubuntu:~> ./repl.sh

Clojure 1.2.1
user=> (load-file “source/algorhythm/test/geometry/trigonometry_tests.clj”)

6. Run all loaded unit tests on the Clojure REPL with (run-tests). They will fail.

user=> (run-tests)

7. Now, write your required functions and repeat the cycle from 5. More specifically in our example, we should be writing algorhythm.geometry.trigonometry and algorhythm.geometry.geometric-vector, that’s required by our example unit test.

Okay, that’s my 2c to help your Clojure baby steps along. Preferably you’d opt for a proper project build system, like Leinigen, instead of manually loading and executing files through the Clojure REPL. But that’s a story for another day…


Zippy Tips Working With ServiceStack, Backbone.js, jQuery & Mono-Develop on Mac

Okay, just some random nigglies I’m experiencing and sort of solved, working with ServiceStack, Backbone.js, Mono & Mono-Develop on Mac.

MonoDevelop & XSP dev web server

Not sure who else is experiencing this issue, but my MonoDevelop and XSP dev web server gets confused sometimes, after a while. I launch two projects when I click play in my project, a web service based on ServiceStack and a ASP .NET project based on Backbone.js. For some weird reason after N number of times relaunching these 2 web projects from MonoDevelop – XSP and MonoDevelop loses track of the web service’s XSP process. The problem then is that I’m unable to re-launch the web service project with a new version.

So… in terminal do “lsof -i -P | grep [port-number-of-xsp-project-website]“. This will give you the XSP process ID. Then, again in terminal, do a “sudo kill [pid]“, to kill the ghost XSP process.

Great now you can continue launching XSP from MonoDevelop.

Cross Domain/Site Scripts with jQuery & Backbone.js

Riiight, so, I was doing the whole preflight thing with jQuery $.ajax. In Firebug I could see the OPTIONS request being made and the server returning the a 200 OK, with the following headers: Access-Control-Allow-Origin and Access-Control-Allow-Methods. BUT, $.ajax never made the actual request to PUT or POST the data to my ServiceStack web service. Well, it turns out another header is required to be returned by the web server’s response to the OPTIONS request: Access-Control-Allow-Headers, with a value of Content-Type.

So when using ServiceStack make sure you set your GlobalResponseHeaders in your AppHosts Configure(…) method:

public override void Configure(Container container)
{
SetConfig(new EndpointHostConfig
{
GlobalResponseHeaders =
{
{ "Access-Control-Allow-Origin", "*" }, // You probably want to restrict this to a specific origin
{ "Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type" }
},
});
}

Saving Models In Backbone.js

When you want to update a model, make sure you call model.save({ anUpdatedProperty: newValue, anotherUpdatedProperty: newValue }), instead of just model.save(), otherwise boggerrol will happen.

When your Backbone.js app talks to a web service that serializes data into a CamelCase format, like C#’s properties, then Backbone’s collection.get(…) won’t work for you, because your model’s id property‘s name will be “Id” and not “id”. To get around this add the idAttribute to your Backbone.js Model, to reroute id to your chosen property on the model object:


var theModel = Backbone.Model.extend(
{
idAttribute: "Id"
});
<pre>

Cool. That’s it for now. Catch you on the flip side!


Discover Dynamic Object Creation In Ruby

Let me quickly explain Ruby‘s dynamic object creation. When I talk about dynamic object creation, I’m referring to when you instantiate a new object instance from meta-data using a class (also referred to a as a Type in .NET) name, or class meta-data object. In languages like C#, and Java you will use reflection to dynamically invoke objects like this. Ruby has two equivalents, depending on whether you’re invoking an object from a class’s name or a class meta-data object. Invoking an object from a class meta data object is very straight forward:

class_meta_obj = Module1::Module2::Module3::SomeClass
return class_meta_obj.new

All you do to instantiate a new object instance from a class definition, is to call new on it.

Invoking an object from a class name is more cumbersome than I think is necessary, because you first need to load each module in the full class name:

class_name = "Module1::Module2::Module3::SomeClass"
result_class_meta_obj = class_name.split('::').inject(Object)
{ |result_class_meta_obj, item|
    result_class_meta_obj.const_get item
}
return result_class_meta_obj.new

First we split the module & class hierarchy on the separator “::”. This gives us each individual module and class in an Array. For each item in the array we pass in the last result returned by the block (result_class_meta_obj), and the current module or class name (item). The argument passed to the inject method (Object) is the first iteration’s last result (result_class_meta_obj).

On the class/module meta object we send the current module/class’s name to const_get. This returns the current module/class’s meta data object, that then becomes the latest result. Each class and module name is a constant in Ruby that points to its corresponding class/module definition. Now that we have the class definition meta data object, we can invoke its constructor the same way as in the first example.


Hey NHibernate, Don’t Mess With My Enums!

So I’ve been using Fluent NHibernate for a short while now. Initially I had to overcome some minor challenges, but since I got those out of the way it’s been pretty smooth sailing. One thing that stands out, which required more tinkering and timeshare than I would’ve liked is the way NHibernate handles the .NET enum type. Natively NHibernate allows you to save your enum’s value as a string or number property/column in the referencing object’s table. In other words, by default it doesn’t allow you to map your enum to its own separate table, and then let your objects refer to it through an association/foreign key. For NHibernate enums are primitive values, and not “entity objects” (logically speaking – ignoring the technical internal mechanics of .NET’s enum). I would argue that enums can be both a primitive string or number, or a more complex entity. Under certain circumstances an enum can be viewed as a simple “object” that consists of two properties:

  • An Id, represented by the enum member’s number value
  • And a name, represented by the enum member’s string name.

I’ve found that it’s very convenient to use the “entity object” version of enums for very simple, slow changing look-up data with a fair amount of business logic attached to it. For instance in a credit application app, you might only support 3 or 4 types of loans, but you know that over time app’s life, the company won’t add more than 2 or 3 new types of loans. Adding a loan type requires some additional work, and isn’t merely a matter of just inserting a new loan type into a look-up table. The reason is that a fair amount of the app’s business logic, mainly in the form of conditional logic statements, must also be adapted to accommodate the new loan type. From a coding perspective it’s very convenient to use enum types in these cases, because you can refer to the various options through DRY strong typed members, with a simultaneous string and number representation. So instead of

var loan = loanRepository.FindById(234);
var loanType = loanTypeRepository.FindById(123);

// ...

if (loan.Type == "PersonalLoan")
{
    // ...
}

rather do

var loan = loanRepository.FindById(234);

if (loan.Type == LoanType.Personal)
{
    //...
}

Okay, schweet, you get the point. Next logical question: How do you get NHibernate to treat your enums as objects with their own table, and not primitive values? To do this you have to create a generic class that can wrap your enum types, and then create a mapping for this enum  wrapper class. I call this class Reference:

public class Reference<TEnum>
{
    private TEnum enm;

    public Reference(TEnum enm)
    {
        this.enm = enm;
    }

    public Reference() {}

    public virtual int Id
    {
        get { return Convert.ToInt32(enm); }
        set { enm = (TEnum)Enum.Parse(typeof(TEnum), value.ToString(), true); }
    }

    public virtual string Name
    {
        get { return enm.ToString(); }
        set { enm = (TEnum)Enum.Parse(typeof(TEnum), value, true); }
    }

    public virtual TEnum Value
    {
        get { return enm; }
        set { enm = value; }
    }
}

The Reference class is pretty straight forward. All it does is translate the contained enum into an object with three properties:

  • Id – the integer value of the enum member.
  • Name – the string name of the enum member.
  • Value – the contained enum member.

You might wonder why I didn’t bother to restrict the allowed generic Types to enums. Well, it so happens that .NET generics doesn’t allow you to restrict generic type declarations to enums. It allows you to restrict generic types to structs, and all sort of other things, but not to enums. So you will never be able to get an exact generic restriction for the Reference class. So I thought, aag what the hell, if I can’t get an exact restriction, then what’s the point anyways? I’ll have to trust that whoever is using the code, knows what he’s doing.

Now, for example, instead of directly using the LoanTypes enum, the Loan class’s Type property will be a Reference object, with its generic type set to the LoanTypes enum:

public class Loan
{
    // ...
    public Reference<LoanType> Type { get; set; }
    // ...
}

This is not completely tidy, because to a degree the limitations of the data access infrastructure, i.e. NHibernate, force us to adopt a compromise solution that’s not necessary if we changed to something else. In other words things from the data infrastructure layers spills into the domain.

What’s left to do is (1) create a mapping for Reference<LoanType>, and (2) get NHibernate to use the right table name, i.e. LoanType, instead of Reference[LoanType]. Here the Fluent NHibernate mapping for Reference<LoanType>:

public class LoanTypeMap: ClassMap<Reference<LoanType>>
{
    public LoanTypeMap()
    {
        Table(typeof(LoanType).Name);
        Id(loanType => loanType.Id).GeneratedBy.Assigned();
        Map(loanType => loanType.Name);
    }
}

The above Fluent NHibernate mapping tells NHibernate to use whatever value property Id has for the primary key, and not generate one for it. You also have to explicitly specify the table’s name you’d like NHibernate to use, because you want to ignore “Reference” as part of the table name, and only use the enum type name.

And that’s it. You will now have a separate table called LoanType, with the foreign keys of other classes’ tables referencing the LoanType enum’s table. Just keep in mind that this solution might not always be feasible. For example it might not work too well when you write a multilingual application. Also should you want to get a pretty description for each enum’s member, for example “Personal Loan”, instead of “PersonalLoan” you’ll have to throw in some intelligent text parsing that split’s a text string before each uppercase character. Hopefully this post gave you another option to map your enum types with NHibernate.