Try fast search NHibernate

08 October 2009

OSS has users, commercial products has customers, ergo p&p is commercial product

This is a long story and I will try to make it short.

In the JAVA ecosystem some projects developers are trying to find a common way to define a specification for a specific problem. After the definition each project can/will implement specification in his way.

For example, have a look : JSR 303 Bean Validation

I know that ask the same attitude in .NET is something really hard… hopefully the CodePlex Foundation will change this fact (if they will extend a little bit their base mission).

My request to Microsoft patterns&practices (Enterprise Library) Validation Application Block was, for far, less than define a new standard… have a look to this thread (don’t forget to pay attention to the dates).

What is that ? It is something so easy as:

namespace uNhAddIns.Adapters
{
///<summary>
///
Contract for the common entity validator.
///</summary>
public interface IEntityValidator
{
///<summary>Returns true if the entity is valid.</summary>
///<param name="entityInstance">
The entity instance.</param>
///<returns>
///
true if the <paramref name="entityInstance"/>
///
has, at least, one invalid value
/// </returns>
bool IsValid(object entityInstance);

///<summary>
///
Validates an entity and returns the information about invalid values.
/// </summary>
///<param name="entityInstance">
The entity instance.</param>
///<returns>
The list of invalid values for the entity.</returns>
IList<IInvalidValueInfo> Validate(object entityInstance);

///<summary>
///
Validates a property of the entity and returns the information about invalid values.
///</summary>
///<param name="entityInstance">
The entity instance.</param>
///<param name="property">
The property. (getter)</param>
///<typeparam name="T">
Type of the entity.</typeparam>
///<typeparam name="TP">
Type of the property</typeparam>
///<returns>
The list of invalid values for the given property.</returns>
IList<IInvalidValueInfo> Validate<T, TP>(T entityInstance, Expression<Func<T, TP>> property) where T : class;

///<summary>
///
Validates a property of the entity and returns the information about invalid values.
///</summary>
///<param name="entityInstance">
The entity instance.</param>
///<param name="propertyName">
The name of one property of the <paramref name="entityInstance"/> </param>
///<returns>
The list of invalid values for the given property.</returns>
IList<IInvalidValueInfo> Validate(object entityInstance, string propertyName);
}
}
namespace uNhAddIns.Adapters
{
///<summary>
///
Contract for the invalid values resulting from a validation.
///</summary>
public interface IInvalidValueInfo
{
/// <summary>
///
This is the class type that the validation result is applicable to. For instance,
/// if the validation result concerns a duplicate record found for an employee, then
/// this property would hold the typeof(Employee). It should be expected that this
/// property will never be null.
/// </summary>
Type EntityType { get; }

/// <summary>
///
If the validation result is applicable to a specific property, then this
/// <see cref="PropertyInfo" /> would be set to a property name.
/// </summary>
string PropertyName { get; }

/// <summary>
///
Holds the message describing the validation result
/// for the EntityType and/or PropertyContext
/// </summary>
string Message { get; }
}
}


Obviously would be nice work together with others teams to create something else than that… for example define some commons interfaces to allow the access to the metadata of validation definitions, for what ? for example the work done in xVal would be a lot more easy.

My dear Alt.NET friends… the team of Microsoft patterns&practices is out.

If you are part of a Validation framework team, would you like to start a real “common validation” project ?

04 October 2009

NHibernate dialect for SQL Azure

As you read in this post there was a little problem running DAOs integration tests directly with SQL-Azure:

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

The problem is generated by this fact :

Because SQL Azure does not support heap tables, a table must have a clustered index. If a table is created without a clustered constraint, a clustered index must be created before an insert operation is allowed on the table.

How run SchemaExport and then run all integration tests having green-field ?

Easy with NHibernate extension points:

public class MsSqlAzureDialect : MsSql2008Dialect
{
public override string PrimaryKeyString
{
get { return "primary key CLUSTERED"; }
}
}
Happy NHibernating on the CLOUD!!

03 October 2009

How you shouldn’t write your mapping

More than one time, in my courses, in this blog and in various NH’s users list, I talked about a rule of thumb about mappings: not try to be clear because it obscures.

Have a look to this mapping:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<
class name="YourApp.Common.DataObjects.Address, YourApp"
table="Address">
<
id name="Id" type="Int32" unsaved-value="null">
<
column name="Id"
length="4" sql-type="int"
not-null="true" unique="true" index="PK_Address"/>
<
generator class="native" />
</
id>
<
property name="Address1" type="String">
<
column name="Address1" length="255"
sql-type="varchar" not-null="true"/>
</
property>
<
property name="Address2" type="String">
<
column name="Address2" length="255"
sql-type="varchar" not-null="false"/>
</
property>
<
property name="City" type="String">
<
column name="City" length="255"
sql-type="varchar" not-null="true"/>
</
property>
<
property name="State" type="String">
<
column name="`State`" length="2"
sql-type="varchar" not-null="true"/>
</
property>
<
property name="Zip" type="String">
<
column name="Zip" length="12"
sql-type="varchar" not-null="true"/>
</
property>
<
many-to-one name="Contact" class="YourApp.Common.DataObjects.Contact, YourApp">
<
column name="Contact_Id" length="4"
sql-type="int" not-null="false"/>
</
many-to-one>
<
bag name="BillToOrderHeaders" inverse="true" lazy="true" cascade="all-delete-orphan">
<
key column="BillToAddress_Id"/>
<
one-to-many
class="YourApp.Common.DataObjects.OrderHeader, YourApp"/>
</
bag>
<
bag name="ShipToOrderHeaders" inverse="true" lazy="true" cascade="all-delete-orphan">
<
key column="ShipToAddress_Id"/>
<
one-to-many
class="YourApp.Common.DataObjects.OrderHeader, YourApp"/>
</
bag>
</
class>
</
hibernate-mapping>

This is how it may look having the same result:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="YourApp"
namespace="YourApp.Common.DataObjects">

<
class name="Address">
<
id name="Id">
<
generator class="native" />
</
id>
<
property name="Address1" not-null="true" />
<
property name="Address2"/>
<
property name="City" not-null="true"/>
<
property name="State" length="2" not-null="true"/>
<
property name="Zip" length="12" not-null="true"/>
<
many-to-one name="Contact" column="Contact_Id"/>
<
bag name="BillToOrderHeaders" inverse="true" cascade="all-delete-orphan">
<
key column="BillToAddress_Id"/>
<
one-to-many class="OrderHeader"/>
</
bag>
<
bag name="ShipToOrderHeaders" inverse="true" cascade="all-delete-orphan">
<
key column="ShipToAddress_Id"/>
<
one-to-many class="OrderHeader"/>
</
bag>
</
class>
</
hibernate-mapping>
In this second representation we can understand immediately which are the difference with the NHibernate convention and, over all, you are not hurting your eyes reading it ;-) .