Flushing in NHibernate

NHibernate has a two layer caching system. The first layer is always active and designed to optimize performance. The second cache is optional and pluggable. You can choose your own provider. The second layer cache is, for example, a good place to cache reference data that doesn’t change so much. If used correctly, the caching mechanism can improve performance significantly.

When changes are made to the persistent objects, they are not immediately propagated to the database. NHibernate stores them in the first layer cache. In this way many changes can be combined into fewer database requests. For example, if a property is updated several times during a session, NHibernate only needs to execute one single SQL update. But when are the changes synchronized with the database? NHibernate calls the synchronization with the database for flushing, and it occurs when:

1) When a transaction commits to make the changes durable.

2) Before a query executes, if the first layer cache contains modified data that affects the result of the query.

3) When the application explicitly calls Flush().

It is also possible to change the default behavior by changing the FlusMode property in the session. As I understand this is not recommended.

NHibernate 2.1.2 Security Constraints

So far I have only tested NHibernate 2.1.0. The latest version is currently 2.1.2. Yesterday I decided to download and install it. I was surprised to find that my unit test wouldn’t execute. The error message said that the NHibernate assembly wasn’t trusted.

Never seen this error before. I thought that I had to grant some permission to the assemblies with Caspol.exe or .Net Framework Configuration tool. It turned out to be easier. In the property dialog for the assembly, there was a new section called security. By pressing the unblock button the assembly became trusted.

1) I deleted all assemblies that is created and copied to the build directory.

2) I keep the referenced assemblies from NHiberenate etc in a lib directory. I unblocked all blocked assemblies in the lib directory.

3) Restarted Visual Studio

4) Rebuild the solution and it was possible to execute my unit tests again.

Favicon

One of the first customization I made to my blog was to add a favicon. A favicon is an icon left to the URL in the address field of the browser.

On the web site http://www.favicon.cc you can generate an icon from a picture. It is easy to include it on the web page. Add the tag <link> (with necessary attributes) within the <head> tag of the html page, for example:

<head>

<title>Peter Nilsson’s .Net Blog</title>

<link rel=”shortcut icon” href=”http://www.peternilsson.me/favicon.ico”/>

</head>

Paint.Net

For a couple of months ago, our home-PC agreement expired. The cost to buy it out was a bit too high, so I decided to return it. I bought a new computer with much better hardware, but it didn’t include so much software. On the home-PC there was a good program to process photos and on my new computer I only had Paint. Pretty soon I missed the magic wand and layers. However, I found a good software that is free and includes many advanced functions for photo processing. It’s called Paint.Net and can be downloaded from http://www.paint.net.

Several sessions in a TransactionScope

I wanted to test concurrency control using optimistic locking in NHibernate and needed a unit test that generated a StaleObjectStateException. To do this I simulated two simultaneous client by two database sessions in the unit test. Both sessions read the same entity, thereafter they modified the content and saved the changes. The last save will cause a StaleObjectStateException, since it violates the ACID rules of the transaction. I run all my tests in a transaction scope and to be able to run several sessions in one transaction scope I had to change the settings for MSDTC on the database server.

1) Open the control panel.

2) Open “Administrative Tools->Component Services”.

3) In the left tree view, navigate to “Component Services->Computers->My Computer”.

4) Right click on “My Computer” and select properties.

5) Select “MSDTC” tab and click on “Security Configuration”.

6) Check “Network DTC Access”, “Allow Remote Client” and “Allow Inbound/Outbound”.

7) Restart service.

NHibernate and Intellisense

NHibernate is OR mapping tool for Microsoft’s .Net platform. It is used to map an object-oriented domain model to a relation database. It also includes features to query and retrieve data. The mapping files are in XML format and it can be a bit hard to know the syntax. Luckily there is support for Intellisense in Visual Studio, which makes it much easier to work with the mapping files. Here is how I set it up for NHibernate 2.1.2 and Visual Studio 2008.

1) Copy the files nhibernate-configuration.xsd and nhibernate-mapping.xsd from the Required_Bins folder in the NHibernate distribution directory.

2) Paste them into C:\Program Files (x86)\Microsoft Visual Studio 9.0\Xml\Schemas.

3) Restart Visual Studio.

GUID in SQL Server

There are many benefits of using GUIDs as the primary key. They are unique across system borders which remove problems with duplicated identities that might occur when working with data from different systems. For example, if the identity of an entity is an integer, two different systems that create the entities will probably have several shared numbers as unique identifiers. This becomes a problem when you, for example, want to merge or replicate data between the systems. The unique constraint will be violated and you have to find a way to work around the problem. During these circumstances, GUIDs are very nice to have because they are unique across system borders.

However, there is a number of drawback also. A GUID requires more resources. It is four times larger than an integer. Which affects the amount of space required to work with GUIDs and also put extra load on I/O and network operations. GUIDs are generated randomly and not sorted. When you generate the next GUID, you don’t know if it is greater or less than previously GUID. Since the GUIDs aren’t generated in an ordered sequence, the index for GUIDs will be fragmented with a high performance penalty. This is not a problem for small databases but a very big problem for larger databases with a lot of inserts.

For system that handles large amount of data, I recommend to avoid GUID and use a sequential id. If it’s really required to have a global unique identity, look at the COMB. COMB is a algorithm to create sequential GUIDs by Jimmy Nilsson.

Transform XML in SQL Server 2005

In my current project one of the systems is used to manage files. The system is able to handle several different file types. Each file type has its own set of meta data. The meta data describes particular characteristics of each file and is stored as XML in the database. Example of meta data is File Type, Tool, Version and Release Information.

The customer wants to generate a description about the file from the meta data. Each file type has it own set of rules on how to generate the description. For example, the description for files of type Misc shall include File Type, Tool and Version. It shall be easy to change the content of a file description and not require a new release of the system.

An appealing solution is to use XSLT to transform the XML based meta data to a description. By storing the XSLT for each file type in the database, it would be easy to change file description during runtime. Since most information aggregation and querying happens in the database, it would be beneficially if we were able to generate the description in the database and use it different views. So how do we transform XML with XSLT in SQL Server 2005?

To solve this problem, I had to create utilities functions in C#, register the assembly in SQL server and to create a function that map one of the utility functions to SQL.

I created two utility functions in C#. One general purpose function used to transform XML with XSLT and one function that specifically is used to generate a file description.

The transform function takes a XML document and a XSLT style sheet and returns the resulting XML data from applying the style sheet on the document.

public static SqlXml Transform(SqlXml xmlData, SqlXml xsltData)

{

//Initialize

MemoryStream memoryXml = new System.IO.MemoryStream();

XslCompiledTransform xslt = new XslCompiledTransform();

// Load XSL transformation

xslt.Load(xsltData.CreateReader());

//Transform

System.IO.MemoryStream ms = new System.IO.MemoryStream();

xslt.Transform(xmlData.CreateReader(), null, ms);

ms.Seek(0, System.IO.SeekOrigin.Begin);

//Return the transformed value

SqlXml retSqlXml = new SqlXml(ms);

string tmp = retSqlXml.Value;

return (retSqlXml);

}

Since I wanted a string, I also created a specific function returning the description from a XML document. This function assumes that the file description is stored in tag called Description. It requires the XML document and XSLT style sheet, and returns the generated file description.

public static string GenerateDescription(string xmlData, string xsltData)

{

string description = “”;

//If missing input, return an empty string

if(string.IsNullOrEmpty(xmlData) | string.IsNullOrEmpty(xsltData))

{

return “”;

}

try

{

//Initialize

StringReader stringXmlReader = new StringReader(xmlData);

XmlReader xmlReader = new XmlTextReader(stringXmlReader);

SqlXml sqlXmlData = new SqlXml(xmlReader);

StringReader stringXsltReader = new StringReader(xsltData);

XmlReader xsltReader = new XmlTextReader(stringXsltReader);

SqlXml sqlXsltData = new SqlXml(xsltReader);

//Transform

SqlXml result = Transform(sqlXmlData, sqlXsltData);

//Get description

XmlDocument xmlDocument = new XmlDocument();

xmlDocument.LoadXml(result.Value);

description =xmlDocument.SelectSingleNode(“Description”).InnerText;

}

catch (Exception e)

{

//TODO: Determine error handling

description = “Error when generating description!”;

}

return description;

}

The assembly can be registered from SQL Server Management Studio Express or by a script. I used the following script to register my assembly.

CREATE ASSEMBLY [Company.CSSS.SqlServer]

AUTHORIZATION [dbo]

FROM ‘C:\Program Files\Company IT\Central System Supporting System\Company.CSSS.SqlServer.dll’

WITH PERMISSION_SET = SAFE

GO

Thereafter you need to enable the CLR. This can also be made from a script.

EXEC sp_CONFIGURE ‘show advanced options’ , ‘1’;

GO

RECONFIGURE;

GO

EXEC sp_CONFIGURE ‘clr enabled’ , ‘1’

GO

RECONFIGURE;

GO

The script that creates the function that maps the utility function to SQL looks like:

CREATE FUNCTION [dbo].[GetFileDescription](@xmlData [nvarchar](4000), @xsltData [nvarchar](4000))

RETURNS [nvarchar](4000) WITH EXECUTE AS CALLER

AS

EXTERNAL NAME [Company.CSSS.SqlServer].[Company.CSSS.SqlServer.XsltTransformer].[GenerateDescription]

GO

Changing format on USB memory stick

I needed some kind of portable device to store larger files. Looked on the Internet and found that there existed 16 GB memory sticks to a quite low price. Looked great and I went to the store and bought one. I had a file bigger than 8 GB that I need to back up. Guess if I was disappointed when I couldn’t copy it to the memory stick. It turned out that the default format was FAT32, which is limited to files of 4 GB. When I pressed RMB, it wasn’t possible to format the memory stick. Mentioned this for a colleague and he know how to change the format. It turned out to be a bit tricky. Here is how you can do it.

1) In the file explorer, use RMB to select properties of the memory stick.

2) Select the Hardware tab.

3) Select your USB device and press Properties.

4) Select the Policy tab.

5) Select Optimize for performance.

6) Now it is possible to format the memory stick to NTFS.