Try fast search NHibernate

28 September 2009

Quick news: NHibernate with SQL-Azure

Just ran DAOs integration tests (the same of this post) in SQL-AZURE.

All work… even the SchemaExport.

well…well… Not all glitters is gold ;)

Exception: “Heaps can not be replicated tables. Please create a clustered index for the table.”

27 September 2009

Testing DAOs : the SetUpFixture Attribute

Usually I’m testing DAOs for CRUD operations. Using NHibernate, as persistent layer, what we are testing, in practice, is the mapping and all behavior we have defined in it (cascade, associations, types, user-types, custom-collections and so on).

For CRUD operation I mean single entity instance CRUD without test complex queries (to test complex-queries I’m using a different test suite with a Well-Known-Data-Base).

Testing NHibernate DAO implementation

The first step is the test of the generic/base implementation of the DAO. To test it I’m mocking NHibernate.

[Test]
public void Get_call_Get()
{
// Arrange
var sessionFactory = new Mock<ISessionFactory>();
var session = new Mock<ISession>();
sessionFactory.Setup(x => x.GetCurrentSession()).Returns(session.Object);

// Act
var dao = new Dao<FakeEntity, int>(sessionFactory.Object);
dao.Get(123);

// Assert
session.Verify(x => x.Get<FakeEntity>(It.Is<int>(id => id == 123)));
}

The CRUD test

A simple integration CRUD test may look like this:

[TestFixture]
public class MagazineTest
{
[Test]
public void MinimalCrud()
{
const int poid = 1;
var m = new Magazine(poid) {Title = "some title"};

var dao = new EntityDao<Magazine>(ServiceLocator.Current.GetInstance<ISessionFactory>());

using (new PersistenceRequest())
{
dao.MakePersistent(m);
ActionAssert.NotThrow(()=> dao.MakePersistent(m));
}

using (new PersistenceRequest())
{
var e = dao.Get(poid);
e.Should().Not.Be.Null();
e.Title.Should().Be.EqualTo("some title");
}

using (new PersistenceRequest())
{
var e = dao.Get(poid);
e.Title = "different title";
}

// should update through NHibernate's UoW
using (new PersistenceRequest())
{
var e = dao.Get(poid);
e.Title.Should().Be.EqualTo("different title");
}

// Delete
using (new PersistenceRequest())
{
var e = dao.Get(poid);
dao.MakeTransient(e);
}

using (new PersistenceRequest())
{
var e = dao.Get(poid);
e.Should().Be.Null();
}
}
}

The PersistenceRequest is an utility class I’m using to simulate the behaviour of the IHttpModule implementing the session-per-request pattern.

Note, the test-fixture does not inherit from a base class and does not have a any SetUp nor TearDown but indeed it need, at least, the configuration of the ServiceLocator, the configuration of NHibernate, the creation of schema, and so on.

For the whole CRUD-test-suite I want execute the configuration of the ServiceLocator, the configuration of NHibernate and its SessionFactory, just only one time and not before execute each test-fixture.

The SetUpFixture Attribute

Since few versions NUnit has a very useful feature: the SetUpFixture Attribute.TestingDaoCrud



To have only one initialization, for all my CRUD-tests, I’m putting all test-fixtures starting from a specific namespace (in the image the namespace is “Cruds”) where I have the implementation of the class, marked with the [SetUpFixture], responsible to create the context for all CRUD tests.


The implementation of the CRUD context look like:
[SetUpFixture]
public class CrudTestContext
{
private WindsorContainer container;

[SetUp]
public void Configure_NHibernate_and_ServiceLocator()
{
container = new WindsorContainer();
container.Register(Component.For<IServiceLocator>()
.Instance(new WindsorServiceLocator(container)));
ServiceLocator.SetLocatorProvider(() => container.Resolve<IServiceLocator>());

container.Register(Component.For<ISessionWrapper>()
.ImplementedBy<FakeSessionWrapper>());
container.Register(Component.For<IConfigurationProvider>()
.ImplementedBy<NhTestConfigurationProvider>());
container.Register(Component.For<ISessionFactoryProvider>()
.ImplementedBy<SessionFactoryProvider>());
container.Register(Component.For<ISessionFactory>()
.Instance(container.GetService<ISessionFactoryProvider>().GetFactory(null)));
}

[TearDown]
public void Close_NHibernate()
{
container.Dispose();
}
}

public class NhTestConfigurationProvider : DefaultSessionFactoryConfigurationProvider
{
public NhTestConfigurationProvider()
{
AfterConfigure += ValidateOrCreateSchema;
}

private void ValidateOrCreateSchema(object sender, ConfigurationEventArgs e)
{
try
{
new SchemaValidator(e.Configuration).Validate();
}
catch (HibernateException)
{
var export = new SchemaExport(e.Configuration);
export.Drop(false, true);
export.Create(false, true);
}
}
}

If you want use the [SetUpFixture] you must use a NUnit2.5 compatible test-runner (ReSharper 4.5 does not support it).

UPDATE : I'm sorry, ReSharper 4.5 does SUPPORT it.

23 September 2009

Sharp Tests Ex 0.3.0 : fluent and lambda assertions for MsTests, NUnit and xUnit

#TestsEx 0.3.0 was released yesterday.

News

The first news is that #TestsEx is no more a “one-man-show”; Jason Diamond is now part of the team.

The second news is that the new syntax, based on lambda expression, is now available (similar to the one available in NUnitEx). You can see an example in the download page.

var var2 = 2;
2.Satisfy(a => var2 == a);
1.Satisfy(a => a == 1 || a != 0);

The mayor advantage of the “Satisfy syntax” is that it is pure C#; perhaps is less readable but you don’t need to know the name of an assertion and its “extensible limit” is the same you have in C#. Even if this feature is available and can be used right now, we are working to improve the failure message.

The breaking change

Perhaps this is the first time I’m happy to announce a breaking change. Starting from this release, to use #TestsEx extensions, you must specify the using clause.

using SharpTestsEx;

Why ? #TestsEx, now can be used with your preferred unit test framework.

We are supporting MsTests, NUnit and xUnit.

For MsTests

You must add the reference to SharpTestsEx.MSTest.dll in your test project.

For NUnit

You must add the reference to SharpTestsEx.NUnit.dll in your test project.

For xUnit

You must add the reference to SharpTestsEx.xUnit.dll in your test project.

For others

For others frameworks you can use SharpTestsEx.dll but, probably, you will see SharpTestsEx in the stack trace of the failure message in your test runner.

If you are working in various projects, using various unit tests frameworks, now you have one more reason to use #TestsEx.

Important

Sharp Tests Extensions is a compendium of commons “extensible extensions” to work with your preferred unit test framework and not another test framework.

The Syntax overview is available here.

Happy testing!!

19 September 2009

Repository or DAO?: DAO

such question, no?
DAO is the anachronism of Data Access Object. On the cloud you can find various definitions of what is a DAO. The follow come from Java ecosystem and is the most complete I found:
The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets. The business component that relies on the DAO uses the simpler interface exposed by the DAO for its clients. The DAO completely hides the data source implementation details from its clients. Because the interface exposed by the DAO to clients does not change when the underlying data source implementation changes, this pattern allows the DAO to adapt to different storage schemes without affecting its clients or business components.
As you can read there isn’t something exactly about how should look a DAO and a DAO can be defined to access data coming from any external source :
Essentially, the DAO acts as an adapter between the component and the data source.
You are completely free to define what each adapter should expose. For example you may have a DAO interface for a UserDAO where its implementations may work with an underling RDBMS, or with Active Directory and so on.
For CRUD operations, with a RDBMS a generic DAO may look as:
public interface IDao<TEntity, TIdentity> where TEntity: IEntity<TIdentity>
{
TEntity Get(TIdentity identity);
TEntity MakePersistent(TEntity entity);
void MakeTransient(TEntity entity);
}
I have used a DAO like that with an ADO.NET implementation. Write the generic implementation for NHibernate is a simple joke.

The problem with DAO is that was defined before powerful persistent-layers, as NHibernate, come in place. Modern persistent layer are tracking any modification you are applying to a persistent Entity and may auto-persist the modification without an explicit call to the DAO. Try to think the difference you have between an implementation using ADO.NET and using NHibernate; using ADO.NET nobody will update an entity state without an explicit call to the MakePersistent method where with NHibernate the modification can be persisted even without call it… a problem ? may be, all depend on how you are writing high layers.

Because the pattern does not define how a DAO should look, two DAOs as the follows are perfectly legal and may coexist in the same application:
public interface IProductDao
{
Product Get(int id);
IEnumerable<Product> FindByDecription(string template);
IEnumerable<Product> FindByPrice(IRange<decimal> priceRange);
void Save(Product product);
void Update(Product product);
void Delete(Product product);
}

public interface ICustomerDao
{
Customer Get(string id);
IEnumerable<Customer> FindByName(string name);
Customer Update(Customer customer);
}
As you can see there are various difference and there isn’t a common interface.

As said in the previous post you can use the Query object pattern to easy extend a DAO but, again, you can even not use it (nobody wrote “Client objects construct query specifications declaratively and submit them to Repository for satisfaction”). If you does not have time to define a good generic IQuery<TEntity> interface, you can use a more simple Criteria object. A Criteria object may look as:
public class CustomerAddressCriteria
{
public string PartialCustomerName { get; set; }
public string StreetName { get; set; }
public CustomerOrder Order { get; set; }
}
public enum CustomerOrder
{
ByNameAscending,
ByNameDescending
}
The DAO is responsible to create the correct query for the underling data-source so construct an SQL, an HQL or even use LINQ is a matter solved inside the DAO implementation (probably this was the reason because many of us are not so worried about a powerful LINQ provider).

Which is the end of this “powerful” and “flexible” pattern ?

As said before the DAO was born some years ago and the IT evolving very fast. If you want stay with a completely switchable interface there is no problem but if you want stop writing methods as FindByDecription, FindByPrice, FindByName, FindByCriteria the next step, at least, is something like:
IEnumerable<TEntity> Retrieve(Expression<Func<TEntity, bool>> predicate);
int Count(Expression<Func<TEntity, bool>> predicate);
and here is where our old friend DAO die because “switchable”, in this case, mean switch between underling system are supporting LINQ… perhaps in these days it mean again any systems… long life to DAO ? ;)

Previous post Repository.

17 September 2009

Configure SessionFactory Providers

This is about a pending task from long time ago… sorry for those waiting for it.

In the AOP example of CpBT you probably saw a class named SessionFactoryProvider; that class was wrote before CpBT and it can be used in others Contexts (ICurrentSessionContext).

ISessionFactoryProvider

The ISessionFactoryProvider is the contract for the implementation responsible for providing NHibernate’s sessionFactory/ies (big fantasy, no?). ISessionFactoryProvider implements IEnumerable<ISessionFactory> and its more important method is:

ISessionFactory GetFactory(string factoryId);

The parameter factoryId is the name you gave to the session-factory configuration:

<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2">
<
session-factory name="Domain_A">

The parameter factoryId, in this case, should be “Domain_A”.

In uNhAddIns there are two implementations: SessionFactoryProvider and MultiSessionFactoryProvider.

IConfigurationProvider

Both implementations, SessionFactoryProvider and MultiSessionFactoryProvider, have a dependency to an implementation of IConfigurationProvider. The responsibility of an IConfigurationProvider is: provide the set of configured NHibernate’s configurations (again big fantasy).

The contract is:

public interface IConfigurationProvider
{
IEnumerable<Configuration> Configure();
event EventHandler<ConfiguringEventArgs> BeforeConfigure;
event EventHandler<ConfigurationEventArgs> AfterConfigure;
}

In the implementation the BeforeConfigure event should be fired just before call configuration.Configure() of each configuration. You can use the event, for example to use the new NHibernate fluent configuration, or to change some property by code, or to set the ByteCodeProvider, or to use the Fluent-NHibernate configuration way, and so on.

The AfterConfigure event should be fired just after call configuration.Configure() of each configuration. You can use the event to add mappings, create the schema, or integrate it with NHibernate.Validator, or anything else you can do after have a configured NHibernate configuration.

The implementation of Configure method should return instances of NHibernate’s configurations ready to call the BuildSessionFactory method.

In uNhAddIns there are two implementations: DefaultSessionFactoryConfigurationProvider and DefaultMultiFactoryConfigurationProvider.

DefaultSessionFactoryConfigurationProvider

Nothing special to say; basically I can resume its behavior as:

var cfg = new Configuration();
cfg.Configure();

DefaultMultiFactoryConfigurationProvider

For multiple session factories what we need are the names of nhibernate’s config files. The configuration is through appSettings:

<configuration>
<
appSettings>
<
add key="nhfactory.WhatEverYouWant" value="AppApersistence.cfg.xml" />
<
add key="nhfactory.TheOther.NH.configFileName" value="AppBpersistence.cfg.xml" />

As you can see there is only a constant part, the “nhfactory”. The DefaultMultiFactoryConfigurationProvider will iterate all settings looking for those have the key starting with “nhfactory” (what follow is important only for you). The value is the name of the file with each NHibernate configuration. As said above what will be important is the session-factory’s name you will specify inside each configuration.

Custom configuration provider

Obviously you can implement your own configuration provider and use it to inject the behavior to a ISessionFactoryProvider (no matter if you will inject it manually or using a DI framework). You can start your own implementation from scratch or inheriting from AbstractConfigurationProvider or inheriting from one of defaults. An example may look as:

public class MyConfigurationProvider : DefaultMultiFactoryConfigurationProvider
{
public MyConfigurationProvider()
{
AfterConfigure += ConfigureCache;
}

private static void ConfigureCache(object sender, ConfigurationEventArgs e)
{
e.Configuration.QueryCache().ResolveRegion("SearchStatistic")
.Using<TolerantQueryCache>().AlwaysTolerant();
}
}

Configuring your DAOs/Repository for multiple DB

This is the real target of this post. In this example I will show an example using Castle.Windsor.

The start point is that you have, at least, two sessions factories configurations in two files (each one will look as an hibernate.cfg.xml you saw in many examples).

The first

    <session-factory name="Domain_A">

and the second

    <session-factory name="Domain_B">

The container configuration through XML should look like

 <facilities>
<
facility id="factorysupport"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</
facilities>

<
component id="sessionFactoryProvider"
service="uNhAddIns.SessionEasier.ISessionFactoryProvider, uNhAddIns"
type="uNhAddIns.SessionEasier.MultiSessionFactoryProvider, uNhAddIns"/>

<
component id="domain_a.sessionFactory"
type="NHibernate.ISessionFactory, NHibernate"
factoryId="sessionFactoryProvider"
factoryCreate="GetFactory">
<
parameters>
<
factoryId>Domain_A</factoryId>
</
parameters>
</
component>

<
component id="domain_b.sessionFactory"
type="NHibernate.ISessionFactory, NHibernate"
factoryId="sessionFactoryProvider"
factoryCreate="GetFactory">
<
parameters>
<
factoryId>Domain_B</factoryId>
</
parameters>
</
component>

<
component id="domain_a.dao.AnEntity"
service='MyCompany.Data.IDao`1[[MyCompany.AnEntity, MyCompany]], MyCompany.Data'
type='MyCompany.Data.Nh.EntityDao`1[[MyCompany.AnEntity, MyCompany]], MyCompany.Data.Nh'>
<
parameters>
<
factory>${domain_a.sessionFactory}</factory>
</
parameters>
</
component>

<
component id="domain_a.dao.AnotherEntity"
service='MyCompany.Data.IDao`1[[MyCompany.AnotherEntity, MyCompany]], MyCompany.Data'
type='MyCompany.Data.Nh.EntityDao`1[[MyCompany.AnotherEntity, MyCompany]], MyCompany.Data.Nh'>
<
parameters>
<
factory>${domain_b.sessionFactory}</factory>
</
parameters>
</
component>

The are two DAOs each one pointing to a different session factory.

If you prefer the configuration by code it should look as:

private const string Domain_A = "Domain_A";
private const string Domain_B = "Domain_B";
private const string SessionFactoryProviderComponentKey = "sessionFactoryProvider";

...

public void ConfigurePersistence()
{
container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();

container.Register(Component.For<ISessionFactoryProvider>()
.Named(SessionFactoryProviderComponentKey)
.ImplementedBy<MultiSessionFactoryProvider>());

RegisterSessionFactoryFor(Domain_A);
RegisterSessionFactoryFor(Domain_B);

RegisterEntityDao<AnEntity>(Domain_A);
RegisterEntityDao<AnotherEntity>(Domain_B);
}

private void RegisterSessionFactoryFor(string sessionFactoryName)
{
container.Register(
Component.For<ISessionFactory>()
.Named(GetSessionFactoryProviderKey(sessionFactoryName))
.Configuration(Attrib.ForName("factoryId").Eq(SessionFactoryProviderComponentKey),
Attrib.ForName("factoryCreate").Eq("GetFactory"))
.Parameters(Parameter.ForKey("factoryId").Eq(sessionFactoryName)));
}

private void RegisterEntityDao<T>(string sessionFactoryName) where T : class, IGenericEntity<int>
{
container.Register(
Component.For<IDao<T>>().ImplementedBy<EntityDao<T>>()
.Parameters(
Parameter.ForKey("factory")
.Eq("${" + GetSessionFactoryProviderKey(sessionFactoryName) + "}")));
}

private static string GetSessionFactoryProviderKey(string sessionFactoryName)
{
return sessionFactoryName + ".sessionFactory";
}

Acknowledgments

Special thanks to those customers allow me to share the knowledge they paid.

13 September 2009

Repository or DAO?: Repository

such question, no?
The definition of Repository pattern is extremely clear (as usual coming from where it come). What was not absolutely clear is how developers are using it… perhaps my interpretation of these words is a little bit extreme.
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
In .NET a Repository should look like:
public interface IRepository<T> : ICollection<T> { }
You may have just one implementation or you may have more than one especially to prevent the calls to Clear.
For example:
public class ProductRepository : IRepository<Product>
{
private readonly ISessionFactory sessionFactory;

public ProductRepository(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}

public void Add(Product item)
{
sessionFactory.GetCurrentSession().Save(item);
}

public void Clear()
{
throw new NotSupportedException();
}
...
}
The other part of the pattern definition say:
Client objects construct query specifications declaratively and submit them to Repository for satisfaction.
With .NET3.5 the Repository should look like:
public interface IRepository<T> : ICollection<T>, IQueryable<T> { }
And the generic implementation for NHibernate should look like:
public class Repository<T>: IRepository<T>
{
private readonly ISessionFactory sessionFactory;

public Repository(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}

#region Implementation of IQueryable

public Expression Expression
{
get { return sessionFactory.GetCurrentSession().Linq<T>().Expression; }
}

public Type ElementType
{
get { return sessionFactory.GetCurrentSession().Linq<T>().ElementType; }
}

public IQueryProvider Provider
{
get { return sessionFactory.GetCurrentSession().Linq<T>().Provider; }
}

#endregion
...
}
That’s all ? … yes that’s all… or that’s should be all.
LINQ is a powerful OO query language but was not designed, in specific, for persistence; in many cases we will must divide the execution in two parts: the part to run in the server and the part to run in RAM. Actually NHibernate has the same concept, through IQuery/ICriteria (server-side) and IResultTransformer (client-side), the main difference is that you are in charge of the decision about “where-run-what”. Implement a LINQ-provider, which is able taking such decisions, is the real feat (I have shown an simple example in this post). So far I didn’t see a persistent-layer that is in condition, always, to take some of these decisions and, frankly, I think it will be very hard; probably, in some cases, we will back to “user decision” with an explicit separation of a linq-sentence in two parts.
Using a Repository interpretation like the above there is another side effect: the responsibility of “how query the persistence” is completely delegated to the business-logic developer. There is no problem because, in general, he is the same guy ? perhaps… I’m not the same guy when I’m implementing the BL than when I’m implementing a DAO (I have tried to explain the problem to my psychologist but he doesn’t understand the problem). In practice Fabio-BL is worried only by OO matters where Fabio-DAL is worried by some OO-matters and, over all, by RDBMS issues. If Fabio-BL has a request like “give me a way to have all Products”, Fabio-DAL will give him a IPaginable<Product> with some restrictions about page-size, or, after some negotiations, an IEnumerable<Product> limited to the first 500 products (no more negotiable).
And before LINQ come in play ?
Here is where I saw everything else than Repository. For example:
public interface IProductRepository
{
Product GetById(int id);
IEnumerable<Product> FindByDecription(string template);
IEnumerable<Product> FindByPrice(IRange<decimal> priceRange);
void Add(Product product);
void Remove(Product product);
}

public interface ICustomerRepository
{
Customer GetCustomerById(string id);
IEnumerable<Customer> FindByName(string name);
void AddCustomer(Customer customer);
}
We can call the two implementations Repository as we can call it Juan, John or whatever; obviously “Repository” sound cool.
The correct way to implements Repository, before LINQ come in play, is using another pattern (the same defined for DAO) : Query object pattern.
The methods in your generic repository may look like:
IEnumerable<T> Retrieve(IQuery<T> query);
long Count(IQuery<T> query);
The challenge, here, is write a good generic IQuery<T> interface.
A little step back : “Repository mediates between the domain and data mapping layers”
Which “data mapping layers” ?
As the DAO even the Repository shouldn’t expose the implementation of the persistent-layer outside the Repository implementation itself and for that reason you shouldn’t use directly “a cooked” query object as NHibernate.ICriteria.
From here on any consideration we can make over “how query the domain” using Repository is applicable to DAO.

Next post DAO.

11 September 2009

NHibernate: Tree Re-parenting

Did you heard about NHibernate and Hibernate re-parenting issue?

I heard it many times in these years including in our JIRA.

Depending on how you are managing your system there are various solutions to manage the re-parenting issue. The most common is set the cascade style to “all” and manage orphaned nodes in some way.

The last time the user said:

Nhibernate should handle cases where child objects are moved from one parent to another by updating the foreign key column in the child record.
Nhibernate should handle cases where child objects are removed from a parent by deleting the orphan objects.

From my understanding I would like cascade=all-delete-orphan to be intelligent enough to handle orphans as orphans and children with new parents not as orphans (they have parents, just not the same ones)
Make sense?

NHibernate is a persistent-layer and rules about how manage a tree are out from persistent-layer scope. The fact that NHibernate offer you the cascade-feature does not mean that it can work in any of your cases especially when the logic is your logic.

Words as “intelligent”/”smart” or “silly” are subjective opinions. In my opinion what is really important is not if a framework is silly or not but if the framework give me the opportunity to define what is intelligent for me.

That said let go to see if NHibernate is the framework I’m looking for.

The repository

Domain

private void FillDb()
{
var rep = new List<Node>();
for (int i = 0; i < 2; i++)
{
var gp = new Node {Description = "N" + i.ToString("00")};
rep.Add(gp);
for (int j = 0; j < 5; j++)
{
var c = new Node { Description = gp.Description + "-" + j.ToString("00") };
gp.AddChild(c);
for (int k = 0; k < 4; k++)
{
var cc = new Node { Description = c.Description + "-" + k.ToString("00") };
c.AddChild(cc);
}
}
}
using (ISession s = sessions.OpenSession())
using (ITransaction tx = s.BeginTransaction())
{
foreach (var node in rep)
{
s.Save(node);
}
tx.Commit();
}
}

Two roots, each with five children and each child with four children.

The target

Usage of delete-orphan cascade-style, making even your DAO/Repository persistence ignorant (no overhead to manage orphans delete).

The test

[Test]
public void TryingDisaster()
{
FillDb();

using (ISession s = sessions.OpenSession())
using (ITransaction tx = s.BeginTransaction())
{
var tree = s.CreateQuery("from Node n where n.Parent is null").List<Node>();


// Move first 2 children of root-0 to root-1
var children = new List<Node>(tree[0].Children);

tree[1].AddChild(children[0]);
tree[1].AddChild(children[1]);

// remove others children from root-1
children = new List<Node>(tree[0].Children);
foreach (var child in children)
{
tree[0].RemoveChild(child);
}

// move all nodes from actual root-1-child-0 to root-0
ReparentingAllChildren(tree[1].Children.First(), tree[0]);

tx.Commit();
}

using (ISession s = sessions.OpenSession())
using (ITransaction tx = s.BeginTransaction())
{
var tree = s.CreateQuery("from Node n where n.Parent is null").List<Node>();

tree.Count.Should("have only two roots").Be.EqualTo(2);

tree.Should("one should have four children")
.Satisfy(a => a.Any(x => x.Children.Count() == 4));

// get the root-1
var root1 = tree.FirstOrDefault(x => x.Children.Count() == 7);

root1.Should("have 7 children").Not.Be.Null();

// one of children should be empty (children was moved to root-0)
root1.Children.Should()
.Satisfy(a => a.Any(x => x.Children.Count() == 0));

// others children, should be intact
root1.Children.Count(c=> c.Children.Count() == 4).Should().Be.EqualTo(6);

tx.Commit();
}
ClearDb();
}

enough ?

The solution

Mapping
<class name="Node">
<
id name="Id">
<
generator class="hilo">
<
param name="max_lo">99</param>
</
generator>
</
id>
<
property name="Description"/>
<
many-to-one name="Parent" access="field.camelcase"/>
<
set name="Children" collection-type="TreeNodesCollectionType"
inverse="true" cascade="all, delete-orphan" access="field.camelcase">
<
key column="Parent"/>
<
one-to-many class="Node"/>
</
set>
</
class>
Custom collection type
public class TreeNodesCollectionType: IUserCollectionType
{
#region Implementation of IUserCollectionType

public IPersistentCollection Instantiate(ISessionImplementor session, ICollectionPersister persister)
{
return new PersistentNodeSet(session);
}

public IPersistentCollection Wrap(ISessionImplementor session, object collection)
{
return new PersistentNodeSet(session, (ISet<Node>)collection);
}

public IEnumerable GetElements(object collection)
{
return (IEnumerable)collection;
}

public bool Contains(object collection, object entity)
{
return ((ISet<Node>)collection).Contains((Node)entity);
}

public object IndexOf(object collection, object entity)
{
throw new NotSupportedException();
}

public object ReplaceElements(object original, object target, ICollectionPersister persister, object owner, IDictionary copyCache, ISessionImplementor session)
{
var result = (ISet<Node>)target;
result.Clear();

foreach (var o in (IEnumerable)original)
result.Add((Node)o);

return result;
}

public object Instantiate(int anticipatedSize)
{
return new HashedSet<Node>();
}

#endregion
}
Custom persistent collection
public class PersistentNodeSet : PersistentGenericSet<Node>
{
public PersistentNodeSet() {}

public PersistentNodeSet(ISessionImplementor session) : base(session) {}

public PersistentNodeSet(ISessionImplementor session, ISet<Node> original) : base(session, original) {}

public override System.Collections.ICollection GetOrphans(object snapshot, string entityName)
{
return base.GetOrphans(snapshot, entityName)
.Cast<Node>()
.Where(n=> ReferenceEquals(null,n.Parent))
.ToArray();
}
}

The custom type and custom persistent collection can be implemented in a more reusable way; where needed we can publish the implementation in uNhAddIns.

Conclusion

Perhaps NHibernate is silly but give you the opportunity to demonstrate your intelligence.

Code available here.

10 September 2009

NHibernate : Queries

How you can query your repository using NHibernate ?

In the NHibernate box you actually having seven ways:

  1. HQL
  2. Criteria
  3. QueryOver
  4. LINQ
  5. H-SQL
  6. SQL
  7. Custom DSL

HQL

HQL is the anachronism of : Hibernate Query Language. HQL, perhaps, is one of the most old and powerful ObjectOriented query system (at list in .NET). In JAVA HQL can be used to query entities persisted even in XML.

In my opinion HQL is the most powerful query system specific for a persistence-layer. Unfortunately, so far, we can’t change the .NET compiler integrating HQL to C# so, HQL is expressed in a string. In JAVA world they have an Eclipse plug-in to support intellisense and refactoring even for HQL but… in our world (.NET) we haven’t it, at least so far (look here ).

HQL does support even DML (obviously all still OO).

You can easy extend HQL through a custom implementation of Dialect.

Criteria

Criteria is a OO query API and is the better solution for dynamic queries (to avoid string concatenation of HQL).

Criteria is even extensible through implementations of ICriterion and IProjection. Using Criteria you can solve the problem of string-concatenation but you still have strings to specify properties names so: you can use Criteria for dynamic queries but there is no reason to use it for static queries.

QueryOver

QueryOver is a new way that will be available in NH3.0.0 (the next mayor release). QueryOver is based on Criteria (with same limitations/power) but, using lambdas expressions, the result clause is more readable and it support property-renaming because it does not suffer the “string” problem.

An example is here.

LINQ

Well… you should know what is LINQ. With NH2.1.0GA (the last release) we have deployed one implementation of a LINQ-provider based on Criteria (with the same limitations Criteria has). Steve Strong is working in a new provider and it will be available with NH3.0.0.

LINQ is a very powerful OO query system but not so specific for persistence. This fact give you a powerful system in memory but make the translation to SQL something complicated.

An example of this fact was reported by Steve in our dev-list

var q = from o in db.Orders
select new
{
o.OrderId,
DiscountedProducts =
from od in o.OrderLines
where od.Discount > 0.0m
select od, FreeShippingDiscount = o.Freight
};

to be efficiently executed we need a part translated to SQL and executed in one db-roundtrip and the other part should be executed in memory. The problem here is that you can’t optimize which should be the behavior with the persistent part as you can do in HQL using the “join fetch” clause.

H-SQL

An H-SQL is basically an standard SQL with some special tags. An example will be better than many words:

var q = session.CreateSQLQuery("select {sim.*} from Simple {sim} where {sim}.date_ = :fred")
.AddEntity("sim", typeof(Simple))
.SetTimestamp("fred", sim.Date);

Specials tags are “{sim.*}” and “{sim}”. The advantage of H-SQL is that you can use any kind of sentence supported by your specific RDBMS mixed we some more OO “tags”.

SQL

SQL is perhaps the most powerful DataCentric language. As HQL and H-SQL you can write your SQL in the mappings and use it through Named-Queries feature so you can write different SQL for different RDBMS without touch your C# code.

If you have a pure DataCentric task to do and you know how do it using SQL you don’t have a valid reason to find its translation using an OO query. For example:

SELECT ID,ClientID,
(SELECT COUNT(*) FROM Clock WHERE ClientID=c.ID AND Status='ON') AS ClocksUp
(SELECT COUNT(*) FROM Clocks WHERE ClientID=c.ID AND Status='OFF') AS ClocksDown
FROM Client AS c

Obviously you can use SQL even as DML

session.CreateSQLQuery("delete from VEHICLE where (TofC = 21) and (Owner = :owner)")
.SetString("owner", "NotThere")
.ExecuteUpdate();

DSL

You can even define your own DSL, to query your domain, and inject the translator through NHibernate’s configuration… but it is absolutely not a trivial task.

NHibernate actually have two available translators: one named “Classic query translator” and the other based on “HQL ANTLR-parser”.

Conclusion

When you have an issue using a “query system” leave the style/taste/fashion matters to Fashion TV and, as a good IT guy, have a look in your tool-box avoiding any kind of fundamentalism.

09 September 2009

NHibernate forks in GitHub

I liked very much this Martin Fowler post about Feature-Branch.

Git seems to be the future for many developers.

As results now you can open a NHibernate fork so easy as few clicks.

The actual list is:

http://github.com/leemhenson/nhibernate/tree/master

http://github.com/chrisortman/nhibernate/tree/trunk

http://github.com/ayende/nhibernate/tree/master

and this other that seem a failing test to open another fork

http://github.com/richardagreene/NHibernate/tree/master

Note each fork, as in Git, may have its own forks.

So… what you are waiting for ?

http://github.com/

The sub title of the site is “Social Coding”.

UPDATE 09/09/09 22:00 GMT-03:00 one fork seem to be removed.

NHibernate in WinForm: coupled

After ten months of public CpBT I still seeing people fighting to find a pattern to manage the NHibernate session in WinForm/WPF.

I’m not sure but perhaps one reason is ours uncoupled examples. So far, in the examples available in uNhAddIns, we have used IoC/DI and AOP, MVP/MVVM/MVC, DAO/Repository trying to show a more real and uncoupled example of a possible application. In this post I have tried to show that Dependency Injection is not the devil implementing a “10 minutes container” (here the code of the container and here the code of its configuration).

This time I’ll try to make a WinForm application, more coupled as possible… perhaps is more easy to uncouple a coupled application than couple an uncoupled.

Targets / Warning

The main target is allow to beginners an easy usage of debugger to follow the execution. I’ll try to avoid any kind of external framework other than NHibernate, NHibernate.Validator and WinForm, avoid any kind of architectural abstraction and so on. In practice the result should be a monolithic WinForms application with object binding.

I know that the final result is not a good example about “how create an WinForm application with NHibernate” but perhaps it will be useful to new users coming from VB6 and/or DataBinding applications.

Preparing the environment

After download the example (see below) what you need is only VisualStudio2008 and MsSQL-EXPRESS. The zip contains NHibernate 2.1.0GA and its dependencies and the last available NHibernate.Validator 1.2.0.

Before run the application you need to create an empty DataBase is your MsSQL-EXPRESS named “Chinook”. You can create it using SQL Server Management Studio Express or using command line:

C:\>sqlcmd -S YourMachine\SQLEXPRESS
1> create database Chinook
2> go

If you want change the DB name remember that you will need to change the connection string in the App.config file:

<property name="connection.connection_string">
Server=(local)\SQLEXPRESS;initial catalog=Chinook;Integrated Security=SSPI
</property>

Quick Show: NHibernate’s session, the Unit of Work

During the first show have a look in the bottom side to see when the hit to DB happens.




The first is a simple input form with object binding an error info; as you saw pressing “OK” two queries are executed: the first to retrieve the high value of HighLow for the Artist entity and the second to insert the new Artist.

In the second part I’m showing two instances of the same form. In instance on the right side, pressing “Add” I’m creating a new instance of the form used for the first part but this time pressing the button “Ok” nothing happen with the DB because the “Jethro Tull” artist is part of a different UnitOfWork (the “Artist Form” is sharing the same NHibernate’s session with “Artists Form” in the right). When I click “Refresh” on the left form the application go to DB to retrieve the refreshed list but nothing change because the UnitOfWork in the right was not committed. When I try to click “Refresh” on the right form a message is showed because there are pending operations in the UoW (the NHibernate’s session is dirty). Finally I’m committing the work of the right form and you can see the hit to DB to insert “Jethro Tull”; at this point the refresh of the left form will find the new Artist instance.

Full Object binding and IDataErrorInfo support

In this show you will see entities implementing INotifyPropertyChanged/IDataErrorInfo and child collection supporting BindingList<T>.




The relationship between Album and Tracks is a classic Master-Details and, as you can see, all is working as data-binding.

Conclusion

If you need some explication about the code, please strictly related to NHibernate usage, you can leave a comment here or you can use the nh-users group.

Download sources!


Another download place is here.

P.S. test everything using only F5 was not so fun for me.

03 September 2009

Why don't choose NHibernate

Well… I’m here again over the same matter… again performance.

This post is about some thoughts after this thread on nhusers list and not strictly a comparison between NHibernate vs EntityFramework.

The comparison

To compare performances I have used again the same environment and the same domain used in this post but, this time, with 50 companies having 50 employees having 50 reports; total entities 127550.

So far I’m NOT an expert in EntityFramework (I’m waiting for EF4) so I have used the same configuration Gergely Orosz have used in his performance test. The code used for NHibernate is the same of the previous post and the code used, to materialize all entities, for EntityFramework is the follow:

using (var ctx = new EFContainer())
{
var companies = from c in ctx.EFCompanySet select c;
foreach (var company in companies)
{
company.Employees.Load();
foreach (var employee in company.Employees)
{
employee.Reports.Load();
}
}
}

The results of the test are

EntityFramework:

Store data seconds: 209,25 ( 209249 miliseconds)
Read data seconds: 57,77 ( 57773 miliseconds)

NHibernate:

Store data seconds: 24,29 ( 24287 miliseconds)
Read data seconds: 24,6 ( 24603 miliseconds)

Which is your conclusion ? NHibernate is faster than EntityFramework ? NHibernate is slow because the materialization of 127550 entities took 24.6” ?

That is what you are seeing ?

My conclusions

The first time I chose NHibernate was because:

  • I’m looking for a persistent-layer based on ORM
  • the license is LGPL
  • its development is based on the mature, and standard de-facto, JAVA world persistent-layer: Hibernate

On what is based your daily work ?

TDD? DDD? code maintainability? business request? YAGNI? easy to implements? XP? dead-line? elegant-code solutions? performance? sprint?

If the performance is the most important concept why you are not programming using assembler instead C# ?

Are you applying only one of these concepts or your work is a continuous balance of each ?

What I’m seeing, in many teams, is that, for various reasons, we are loosing the most important concept: the balance of each.

In front of the question “why you chose this solution ?” many times the answer is “because the dead-line is tomorrow” or “because it is the minimal code to pass my test” and so on. The worst results is not the mere answer itself but what will happen after… perhaps when you have a performance issue. If you saw that the solution you have chose does not satisfy the expectance why, rethink the whole solution, shouldn’t be an option ?

Have a quick look to your toolbox perhaps you having the right tool to solve the issue. What ? using that tool the code is not elegant ? it will be more hard to maintain ? it is more hard to implements ?… and? which is the main target of that specific task ?

As you can see above a persistent-layer based on ORM is not the right tool to perform bulk operations, is not the right tool to perform massive data mining, is not the right tool to provide data for OLAP cube… this mean that a persistent-layer based on ORM is not a good tool ? absolutely NOT my friend, that only mean that in your application you have a lot of different tasks and you should choose the right tool for each specific task…have a look to your toolbox!!!

02 September 2009

Data mining in 5 minutes

Today, a friend of mine asked me to create two examples of C# WinForm applications (one using .NET3.5 and other using .NET2.0).

The target, so far, is only a proof of concept to check how extend an existing application to show some information from an existing ORACLE DB.

My friend said me: “If you want use NHibernate there is no problem.”

You know… NHibernate is not the best tool for data mining especially when the source of data is a plain view.

Well… the result of the story was: five minute per each application using only the mouse.

Learning some .NET new concepts

In the last “Alt.NET Hispano cafĂ©” I have learned some new concepts.

Assertions: “The framework I like have all those things solved”; “The framework I like is an example of how encapsulate the complexity”

This is how look a property get-set using that framework:

private static PropertyInfo<string> NameProperty =
RegisterProperty<string>(p=>p.Name, "Project name");
public string Name
{
get { return GetProperty(NameProperty); }
set { SetProperty(NameProperty, value); }
}

private static PropertyInfo<SmartDate> StartedProperty =
RegisterProperty<SmartDate>(p=>p.Started);
public string Started
{
get { return GetPropertyConvert<SmartDate, string>(StartedProperty); }
set { SetPropertyConvert<SmartDate, string>(StartedProperty, value); }
}

Note the Started property is a “special” DateTime.

The follow is how look the fetch by ID:

private void DataPortal_Fetch(SingleCriteria<Project, Guid> criteria)
{
using (var ctx =
ContextManager<ProjectTracker.DalLinq.PTrackerDataContext>.
GetManager(ProjectTracker.DalLinq.Database.PTracker))
{
// get project data
var data = (from p in ctx.DataContext.Projects
where p.Id == criteria.Value
select p).Single();
LoadProperty(IdProperty, data.Id);
LoadProperty(NameProperty, data.Name);
LoadPropertyConvert<SmartDate, System.DateTime?>(
StartedProperty, data.Started);
LoadPropertyConvert<SmartDate, System.DateTime?>(
EndedProperty, data.Ended);
LoadProperty(DescriptionProperty, data.Description);
_timestamp = data.LastChanged.ToArray();

// get child data
LoadProperty(
ResourcesProperty,
ProjectResources.GetProjectResources(
data.Assignments.ToArray()));
}
}

My personal response to the assertion is : the framework you like may have “all things solved” but somebody, or something, should write that plumbing code for me; about the “encapsulation of complexity” perhaps you are talking about some other kind of complexity because I can't see where is the “encapsulation”.

Assertion: “What you are doing is only for genius/aliens”

What the altnetter guy, that obviously is not the same of the assertions, was showing was:

public class Track : Entity
{
public virtual string Name { get; set; }
public virtual Album Album { get; set; }
public virtual MediaType MediaType { get; set; }
public virtual Genre Genre { get; set; }
public virtual string Composer { get; set; }
public virtual int Milliseconds { get; set; }
public virtual int Bytes { get; set; }
public virtual decimal UnitPrice { get; set; }
}

The follow is how look the fetch by ID:

public T Get(object id)
{
return Session.Get<T>(id);
}

Note: the code is a generic implementation that mean that even in presence of a parent-child relationship or anything else the line to execute is the same.

My personal response to the assertion is: if how we are working is understandable only by genius/alien I must talk with my mother (perhaps “The Visitors” was not only a TV fiction).

01 September 2009

Test runner poll : results

My conclusion is:

Developers prefer solutions integrated with IDE to run tests during development.