Why Fluent NHibernate?

70 views
Skip to first unread message

Rafael Rosa

unread,
Nov 18, 2008, 6:37:48 PM11/18/08
to sharp-arc...@googlegroups.com
Hi,

In the first place, I'm neither complaining or criticizing :)

I'm a Castle ActiveRecord user and I really like it, and so does a big community. I've seem Fluent NHibernate, a friend told he is using it and liking it very much, as so does lots of other people. But I can't get out of my head one of Ayende's comments about it, and after reading quite a few discussions about it, I gathered some general complaints:

1 - "I don't like the relation attributes poluting my model" - Ok, I don't think they are pretty also, but I do think that there's a good reason to put them on the model: their relationship is meaningfull to the domain. If I look, for example, at a ShoppingCartItem object I want to know who's his father, if he has dependencies, etc, and how they are supossed to work (one to many, many to many, etc). I don't want to know the details of the implementation, but I do want to know the logical relationships.

2 - "You have to inherit the objects from ActiveRecordBase" - not true. Even though this is an option, maybe the quick option, you can use a Repository Pattern without effort, eliminating the reason for this complaint.

I saw the discussion over validation methods and in the end will need to "polute" the model with NHibernate.Validator attributes to accomplish part of that. Then, why not use Castle's validators, which can be used to validate other things other than NHibernate stuff?

I'm studding which changes would be necessary to re-implement the sample application to use ActiveRecord, so I can show something a little more substantial.

I'm digging #Arch, but there are some points in which I have some doubts and maybe some discussion can help. I'm sure you all, specially Billy, have spent a lot of time thinking about the pros and cons of each choice, and I'd like to understand them better.

Cheers,
Rafael.

Billy

unread,
Nov 18, 2008, 7:32:23 PM11/18/08
to S#arp Architecture
Hi Rafael,

Thanks for the questions as they provide some good points of
clarification.

I've used Castle ActiveRecord as well and had great experiences with
it on a couple of smaller ecommerce sites. Personal experience over a
number of projects has led me down the path towards domain driven
rather than a model driven design. I feel that ActiveRecord, like the
ADO.NET Entity Framework is more reflective of the latter - being
model driven - and not something I tend to use on a large project.
This is simply my personal preference and not a reflection of the
quality of these alternatives for the problems that they are trying to
solve.

With respect to attributes polluting the model, there aren't any
association attributes used within #Arch; assuming
NHibernate.Mapping.Attributes is what your alluding to. The Fluent
NHibernate mapping classes are stored within the MyProject.Data
assembly; so the domain layer is completely ignorant of their
existence - pollutant free if you will. Let me know if I've
misinterpreted your first comment.

Concerning the inheritance of a base object, there's no need to
inherit from a base object in #Arch, such as DomainObject or
PersistentObject. These base classes are simply helpers for providing
a consistent means of storing the ID of objects and comparing them to
others. The data access code, such as the
SharpArch.Data.NHibernate.Repository base repository class doesn't
care what the persisted object is (or inherits from) as long as it has
a mapping file associated with it, be it HBMs, mapping attributes, or
class maps.

As you noted, Castle's validators are also a great validation
mechanism. Although #Arch includes support for NHibernate.Validator
out of the box, there's nothing to preclude you from using an
alternative validation utility. Although NHibernate.Validator forces
the addition of a reference to it, it doesn't oblige a reference to
NHibernate as well; so it should really be seen as a quality
validation framework which just happens to work very nicely with
NHibernate - NHibernate.Validator may be leveraged without the use of
NHibernate. When it came down to it, I wanted to have a preferred
validation framework (it looks like "opinionated" is the new buzzword
in the blogsphere ;) while having seemless integration with
NHibernate. NHibernate.Validator fit the bill nicely.

Finally, I don't think that ActiveRecord would be a good choice for
#Arch; IMO, it defeats the purpose of the current architecture which
provides - indeed forces - a clean separation between business logic
and data access concerns while emphasizing domain driven design. As I
mentioned, ActiveRecord is a terrific framework for model driven
development, but not in alignment with the fundamental motivations of
#Arch. With that said, a specialized base foundation, inspired by
#Arch but leveraging ActiveRecord, might make a great codeproject.com
article or even a new OSS project, as a couple others have done.

Billy

Rafael Rosa

unread,
Nov 18, 2008, 8:10:08 PM11/18/08
to sharp-arc...@googlegroups.com
Hi,

I think my questions weren't clear, maybe because I forgot to add this link to Ayende's post, or my English is terrible :)

I'm using ActiveRecord in it's basic form in my current project, but I was convinced by some friends' experience that the Repository Pattern is very useful, and I decided to try it. The main question is why use Fluent NHibernate to make the mappings if this forces us to create a second class to do just that? The key about Ayende's comment is "if I need to touch 2 places, something is wrong". I'm not suggesting to use the basic implementation of ActiveRecord, but use it to define the models and let it do all the mapping stuff, instead of create another class.

For example, this is the current Category implementation:

    public class Category : PersistentObject
    {
        public Category() { }
        public Category(string name) {
            Name = name;
        }

        [DomainSignature]
        [NotNullNotEmpty]
        public virtual string Name { get; protected set; }
    }

And this is the mapping class:

    public class CategoryMap : ClassMap<Category>, IMapGenerator
    {
        public CategoryMap() {
            WithTable("Categories");

            Id(x => x.ID, "CategoryID")
                .WithUnsavedValue(0)
                .GeneratedBy.Identity();
           
            Map(x => x.Name, "CategoryName");
        }
        public System.Xml.XmlDocument Generate() {
            return CreateMapping(new MappingVisitor());
        }
    }

Using ActiveRecord for mapping would be something like this:

    [ActiveRecord]
    public class Category : PersistentObject
    {
        public Category() { }
        public Category(string name) {
            Name = name;
        }

        [PrimaryKey]
        public virtual int ID;
        [DomainSignature]
        [Property, ValidateNonEmpty]
        public virtual string Name { get; protected set; }

        [HasMany(typeof(SubInformation))]
        public virtual IList<SubInformation> {get; set;}
    }

That's it, no mapping class, and I even added a sub property just to show a has many relationship. We could change the PersistentObject class so it automaticaly adds the ID property as the primary key, eliminating the need to declare it here. The best part is that you have just on place to look, one class to worry about, and the object under it is still POCO, as much as before anyway.

The repositories are keept almost the same, but just add an implementation of ActiveRecordRepository, which in fact will call ActiveRecordMediator and we won't need to make any effort to talk to NHibernate. If we want to validate the model, just add the necessary attributes, which is already done today, and bingo. The project modules (Core, Data, Controllers, Web and Tests) remains the same, the details os quering repositories and stuff kept inside Data, with the repositories implementation.

I don't think that this approch break DDD, it just eliminates the need to have an extra class to worry about. Everything else still works: schema generation, custom NHibernate configuration, etc, plus it adds the expertise and seasoning of Castle project. There are a lot of interesting tools in RhinoCommons too, but it lacks good documentation (at least for newcomers) or good examples.

As I said, this is just an idea, another way to make some things. As I said before, I'll re-implement the Northwind project with these tools so I can show what I mean. At least, will know how dificult is to change some of the tools in place today, and might generate some ideas of how this can be made easier.

Cheers,
Rafael.

Luis Abreu

unread,
Nov 19, 2008, 3:54:59 AM11/19/08
to sharp-arc...@googlegroups.com
I've only looked at active record and, as Billy said, it's a good
framework, but not one I'd use in a DDD project for sure.

regarding the "if I need to touch 2 places, something is wrong", I
still can't believe Ayende said that, especially because I know he
uses R#. I've been using fluent nhibernate for some time and even
though it has one or two bugs, I can't really count the number of ways
it has helped me maintain the mapping consistency between my classes
and my tables. The biggest problem most people face with the
traditional mapping xml files is that refactoring isn't supported
there (ok, there was a r# plugin that was supposed to do that, but I
think it never worked out very well). With fluent nhibernate, for
instance, I can only do a simple renaming on a property and know that
it will be propagated onto the mappings. And as Billy said, you can
put the mappings on your repository assembly and you'll still have
POCO. That won't happen with attributes...

One more thing regarding validation: even though I still haven't
looked at nhibernator validator, I'm positive that validation is
really a concrete domain aspect and I'm a believer that it should be
put inside the domain base assembly. What I'm saying is that it is
possible to add some basic core interfaces and base classes for
validation and they should be inside the core assembly and know
nothing about any data access details (ok, I haven't looked at the
last bits, so I don't know how validation was added to it. what I',
proposing is adding some sort of methods that would do 2 things: give
broken validation rules and give the broken rules when an object would
be transitioning from the current state to an hipotetical future
state)...


--
Regards,
Luis Abreu

Neo

unread,
Nov 20, 2008, 11:12:27 AM11/20/08
to S#arp Architecture
I'm not sure if this was the right time to start working with Fluent
NHibernate library, as it lacks documentation.
I had to restructure my code, and until now I couldn't pass all the
tests.
Its pretty hard to put things to work when it kept throwing exceptions
that you know why but cant find out a
way to solve it.

One of the problems I'm facing and cant find a solution is on enum
mapping.
Maybe I can get an answer from you guys. Here's what I have:

public class Person : PersistentObject
{
//other properties and constructor

public virtual ISet<Contact> Contacts { get; protected set; }
}

public class Contact : PersistentObject
{
[DomainSignature]
public virtual ContactType Type { get; set; }
[DomainSignature]
public virtual string Description { get; set; }
}

public enum ContactType
{
Email = 1,
Phone
}


And my Person mapping looks like this:

HasMany<Contact>(person => person.Contacts)
.AsSet()
.WithTableName("Contact")
.WithKeyColumn("Per_Id")
.Component(ct =>
{
ct.Map(c => c.Type, "ContactType")
.CanNotBeNull();
ct.Map(c => c.Description,
"Description")
.CanNotBeNull();
});

This is the thrown exception when trying to get all Person:

NHibernate.HibernateException : Can't Parse 1 as ContactType
----> System.ArgumentNullException : Value cannot be null.
Parameter name: value

This was my old mapping, it used to work:

<set name="Contacts" table="Contact" lazy="true">
<key column="Per_ID" />
<composite-element class="Contact">
<property name="Type" column="ContactType" not-null="true"
type="short"></property>
<property name="Description" not-null="true"></property>
</composite-element>
</set>

The only thing I see its not exactly like the Fluent way is that
'type' attribute on Type property.
I've tried this also:

HasMany<Contact>(person => person.Contacts)
.AsSet()
.WithTableName("Contact")
.WithKeyColumn("Per_Id")
.Component(ct =>
{
ct.Map(c => c.Type, "ContactType")
.CanNotBeNull().SetAttribute
("type", "short");;
ct.Map(c => c.Description,
"Description")
.CanNotBeNull();
});

Resulting the same exception.

--
Neo

Luis Abreu

unread,
Nov 20, 2008, 12:59:41 PM11/20/08
to sharp-arc...@googlegroups.com
I'm using something very similar for mapping enums...the only difference I
see is that I'm not using the CanNotBeNull method call...

Any more info on the stack from the exception?

--
Luis Abreu
> Internal Virus Database is out of date.
> Checked by AVG - http://www.avg.com
> Version: 8.0.175 / Virus Database: 270.9.3/1786 - Release Date: 16-11-
> 2008 10:04

Neo

unread,
Nov 20, 2008, 2:01:13 PM11/20/08
to S#arp Architecture
Luis, did your code work?

I've tried a few thing, but nothing helped that much.

This is the stack trace:

at NHibernate.Type.EnumStringType.GetInstance(Object code)
at NHibernate.Type.EnumStringType.Get(IDataReader rs, Int32 index)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String
name)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[]
names, ISessionImplementor session, Object owner)
at NHibernate.Type.AbstractType.Hydrate(IDataReader rs, String[]
names, ISessionImplementor session, Object owner)
at NHibernate.Type.ComponentType.Hydrate(IDataReader rs, String[]
names, ISessionImplementor session, Object owner)
at NHibernate.Type.ComponentType.NullSafeGet(IDataReader rs, String[]
names, ISessionImplementor session, Object owner)
at
NHibernate.Persister.Collection.AbstractCollectionPersister.ReadElement
(IDataReader rs, Object owner, String[] aliases, ISessionImplementor
session)
at NHibernate.Collection.Generic.PersistentGenericSet`1.ReadFrom
(IDataReader rs, ICollectionPersister role, ICollectionAliases
descriptor, Object owner)
at NHibernate.Loader.Loader.ReadCollectionElement(Object
optionalOwner, Object optionalKey, ICollectionPersister persister,
ICollectionAliases descriptor, IDataReader rs, ISessionImplementor
session)
at NHibernate.Loader.Loader.ReadCollectionElements(Object[] row,
IDataReader resultSet, ISessionImplementor session)
at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet,
ISessionImplementor session, QueryParameters queryParameters, LockMode
[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects,
EntityKey[] keys, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session,
QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections
(ISessionImplementor session, QueryParameters queryParameters, Boolean
returnProxies)
> > Checked by AVG -http://www.avg.com

Luis Abreu

unread,
Nov 20, 2008, 2:14:42 PM11/20/08
to sharp-arc...@googlegroups.com
Yes, it's working...

I've also noticed that you're using the setattribute call for specifying a
short...does it work with an integer (ie, if you remove that attribute, does
it work)?
> Checked by AVG - http://www.avg.com

Luis Abreu

unread,
Nov 20, 2008, 2:31:19 PM11/20/08
to sharp-arc...@googlegroups.com
That's really weird...I've reviewed na old post I've written on it and it
seems like the only place where I had to perform a cast was on the
discriminate subclass thingy (I had an int column on db and while trying to
pass the enum directly, it kept trying to save a string, which wasn't what I
wanted). On the other places where I had enums, I didn0t had any problems
with it. Btw, the post I mention is here:

http://msmvps.com/blogs/luisabreu/archive/2008/10/24/using-the-new-fluent-nh
ibernate-project.aspx


and the only thing that I remember was a bug related with the place where
you call the discrimante subclass method...
> > > Version: 8.0.175 / Virus Database: 270.9.3/1786 - Release Date: 16-
> 11-
> > > 2008 10:04
> >
> Internal Virus Database is out of date.
> Checked by AVG - http://www.avg.com

Neo

unread,
Nov 21, 2008, 7:22:12 AM11/21/08
to S#arp Architecture
Hi Luis.

I tried something different here.

I set up the contact map in a different class and mapped it this way:

At PersonMap:
HasMany<Contact>(person => person.Contacts)
.WithTableName("Contact")
.WithKeyColumn("Per_Id")
.AsSet();

At ContactMap

Id(contact => contact.ID)
.GeneratedBy
.Sequence("HIBERNATE_SEQUENCE");

Map(ct => ct.Type, "ContactType")
.CanNotBeNull();
Map(ct => ct.Description)
.CanNotBeNull();

References(contact => contact.Owner)
.WithForeignKey("Per_Id");

Now I got an Sql Error exception.
Looking at the query generated, it has an invalid character

Person person0_
inner join [Contact] contacts1_ on
person0_.Id=contacts1_.Per_Id

[Contact] <- this is the problem, it should be Contact, not [Contact]

Why NHibernate is enclosing the Contact???

Problem after problem... I'm getting out of patience, lol.

Neo

On Nov 20, 5:31 pm, "Luis Abreu" <lab...@gmail.com> wrote:
> That's really weird...I've reviewed na old post I've written on it and it
> seems like the only place where I had to perform a cast was on the
> discriminate subclass thingy (I had an int column on db and while trying to
> pass the enum directly, it kept trying to save a string, which wasn't what I
> wanted). On the other places where I had enums, I didn0t had any problems
> with it. Btw, the post I mention is here:
>
> http://msmvps.com/blogs/luisabreu/archive/2008/10/24/using-the-new-fl...

Rodrigo Matias Leote

unread,
Nov 21, 2008, 7:47:53 AM11/21/08
to S#arp Architecture
No way man.

I can only say it's a Fluent NHibernate bug.
This SHOULD work:
HasMany<Contact>(person => person.Contacts)
        .WithTableName("Contact")
        .WithKeyColumn("Per_Id")
        .Component(ct =>
                     {
                       ct.Map(c => c.Type, "ContactType").
                         .CanNotBeNull().SetAttribute("type", "short");
                       ct.Map(c => c.Description, "Description")
                         .CanNotBeNull();
                     }).AsSet();

Because I have the same map as XML and worked sweetly:
<set name="Contacts" table="Contact" lazy="true">
      <key column="Per_ID" />
      <composite-element class="Contact">
        <property name="Type" column="ContactType" not-null="true" type="short"></property>
        <property name="Description" not-null="true"></property>
      </composite-element>
    </set>

Regards,
Neo
--
Abraço!

Rodrigo Matias Leote
.NET Programmer
Dataweb Tecnologia

"Whatever the mind can conceive and believe, the mind can achieve." - Dr. Napoleon Hill

Luis Abreu

unread,
Nov 21, 2008, 7:38:34 AM11/21/08
to sharp-arc...@googlegroups.com
> Person person0_
> inner join [Contact] contacts1_ on
> person0_.Id=contacts1_.Per_Id
>
> [Contact] <- this is the problem, it should be Contact, not [Contact]
>
> Why NHibernate is enclosing the Contact???

i think that won't be problematic...what nh is doing is escaping the
name to make sure that it's not using any sql reserved term (putting
[] will "escape" the word you're using).

I've noticed that I've performed some changes on the mappings and I've
ended up using integers. Here's my code:

HasMany<Contact>(branch => branch.Contacts)
.AsSet()
.WithTableName("Contactos")
.WithKeyColumn("IdFilial")
.Component(ct =>
{
ct.Map(c => c.Kind, "TipoContacto")
.CustomTypeIs(typeof (ContactKind))
.CustomSqlTypeIs("integer");
ct.Map(c => c.Value, "Contacto");
});

Where:
ContactKind is the enumeration
CustomSqlTypeIs is the sql type on th bd.

See if this works for you. if it doesn't, you can always set the
CustomTypeIs to Int32 and it should work without any problems.


--
Regards,
Luis Abreu

Rodrigo Matias Leote

unread,
Nov 21, 2008, 7:52:15 AM11/21/08
to sharp-arc...@googlegroups.com
Man!!!
It worked like a charm!

The only difference is that I set
.CustomSqlTypeIs as short, since I have short type in my database.

Now all my tests worked again.
Thank you so much!

Regards,
Neo

Billy

unread,
Nov 21, 2008, 10:05:52 AM11/21/08
to S#arp Architecture
Great call Luis! Neo, does this resolve your issue as well?

Billy

Neo

unread,
Nov 21, 2008, 10:43:43 AM11/21/08
to S#arp Architecture
Yeah! It resolved!

Thanks!

Regards,
Neo

Billy

unread,
Nov 24, 2008, 5:48:04 PM11/24/08
to S#arp Architecture

Rafael

unread,
Nov 27, 2008, 2:38:37 PM11/27/08
to S#arp Architecture
Billy,

Thanks for the links, they are really nice, full of good information.

I do understand the advantages of Fluent NHibernate, but I still don't
think it's better than Castle ActiveRecord. Being able to look at the
domain objects and see how they are connected and how they are
validated in just one place is something that improves code
readability and is more intention revealing, and I'd rather have
attributes attached to them than having a separated code file for the
mapping, even though this is much better than XML.

I'll work on an alternate Northwind implementation so I can show what
I mean, but I've being quite busy these last few weeks.

Cheers,
Rafael.

Luis Abreu

unread,
Nov 27, 2008, 2:49:06 PM11/27/08
to sharp-arc...@googlegroups.com
Rafael,

If i recall correctly, ActiveRecord is trying to implement this pattern:

http://en.wikipedia.org/wiki/Active_record_pattern

This is completely different from the DDD approach that the platform tries
to use. I'm not saying this is bad, just that it's different...

--
Luis Abreu


> -----Original Message-----
> From: sharp-arc...@googlegroups.com [mailto:sharp-
> archit...@googlegroups.com] On Behalf Of Rafael
> Sent: Thursday, November 27, 2008 7:39 PM
> To: S#arp Architecture
> Subject: Re: Why Fluent NHibernate?
>
>
> No virus found in this incoming message.
> Checked by AVG - http://www.avg.com
> Version: 8.0.176 / Virus Database: 270.9.10/1813 - Release Date: 27-11-
> 2008 09:02

Rafael

unread,
Nov 27, 2008, 3:44:13 PM11/27/08
to S#arp Architecture
Hi Luis,

The answer is Yes and No :) The standard use of Castle ActiveRecord
does implement the Active Record pattern, it was inspired by Ruby on
Rails as well. But, if you want, you can also use it with the
Repository pattern and use it's attributes to do the object's mapping
and access then using a custom repository or some other built in
features. Take a look at my second post so you can see how you can
declare an object in this way, and the following links to see a little
bit more of code:

http://www.castleproject.org/activerecord/documentation/trunk/advanced/mediator.html

I'm not saying that Fluent NHibernate is a bad choice, but I'd rather
have more information about the object's relationships on my domain
model and skip the need for a mapping class. These informations
doesn't necessarily refer to the implementation, like table names and
the like, you can treat this somewhere else when you need it. However,
when dealing with legacy databases Fluent NHibernate have some
advantages, but I think that Castle's ActiveRecord is better for
greenfield projects or when your database is designed with an ORM in
mind, so these two can get along smoothly.

Cheers,
Rafael.

Luis Abreu

unread,
Nov 27, 2008, 4:13:36 PM11/27/08
to sharp-arc...@googlegroups.com
> The answer is Yes and No :) The standard use of Castle ActiveRecord
> does implement the Active Record pattern, it was inspired by Ruby on
> Rails as well. But, if you want, you can also use it with the
> Repository pattern and use it's attributes to do the object's mapping
> and access then using a custom repository or some other built in
> features. Take a look at my second post so you can see how you can
> declare an object in this way, and the following links to see a little
> bit more of code:

Yes, I'm not discussing which way is better. Personally, I prefer to have
POCO, but that's my opinion only. There's probably nothing wrong with tying
the properties/fields to table fields through attributes. As I've said, I do
prefer POCOs and in this case, I do see some advantages on using fluent NH.
However, if you don't want to go with POCOs, then there really isn't much I
have to say about the way you set up the relationships...

What I'm saying is that it's not DDD. If you really look at a well modeled
DDD app, you'll notice that you tend to have lots of methods used for
interacting with objects (and that's natural because methods tend to be more
"descriptive" than properties and one of the main objectives of DDD is
having a model which is easily understood by everyone that knows the
ubiquitous language of that domain). Ok, so do I use properties/fields? Yes,
I do that and NH is configured for loading them from the database, but the
difference is that on my domain, most interactions are not done through
properties, but through method calls.

Luis

Rafael

unread,
Nov 27, 2008, 4:25:05 PM11/27/08
to S#arp Architecture
I really can't see why using this approach for mapping is no DDD, and
I why decorating objects with attributes makes them less POCO. The
approach I'm talking about doesn't need to use a complex base class,
so you won't be hiding a lot of stuff under the hood. The attributes
won't change the object's behavior, will be meaningful just when you
use the ActiveRecord engine to do the dirty work, just like Fluent
NHibernate when it's using the mapping class. You can put as many
methods as you want, to do whatever you need, there's no difference
there, the only change is how the objects will be mapped.

I also think that POCO is good and I cannot see how this breaks the
rules.

Cheers,
Rafael.

Luis Abreu

unread,
Nov 27, 2008, 4:38:20 PM11/27/08
to sharp-arc...@googlegroups.com
Hello again.

>
> I really can't see why using this approach for mapping is no DDD, and
> I why decorating objects with attributes makes them less POCO. The

No, no, no, that's not what I'm saying:) (mapping with attribs is not DDD).
Regarding the POCO, adding the attributes means that your objects end up
"knowing" details about the db and you end up adding an unnecessary
reference to the active record assembly (at least, that is what happens when
you use attributes with NH). With the xml file or NH fluent that doesn't
need to happen because you can build your domain assembly without any
references to NH assemblies (ok, not sure if that is true with the current
version of this framework, but I think it should be). Having said this, if
you don't want to use POCO, there's nothing wrong with the attributes...

Luis

Rafael

unread,
Nov 27, 2008, 5:23:50 PM11/27/08
to S#arp Architecture
Hi Luis,

Ok, agreed on DDD :)

As for POCO, well, not linking the domain objects library to some
external framework references is something I don't believe we can ever
achieve, unless we're working with very simple objects. The need for
validation is the first thing that comes to my mind, and things like
DomainSignature, for example, are very useful and I think that
outweighs the problems of referring a few external libraries.

On the other hand, adding another class to do the mapping obscures the
code, makes us search basic informations about our model in two
different places, and that's something that I qualify as much more
important than linking one or two external libraries, and in the case
o ActiveRecord you don't need to reference NHibernate's.

As for DB implementation details, if you build your objects correctly
and makes your DB schema comply to your objects structure, not the
other way around, you won't need to give any details about
implementation on the attributes, just make explicit the logical
relationships, which will make the code clearer. For example, if you
have all your tables named after the objects and all table's fields
name after your objects properties, them you don't need to specify the
implementation name in the attributes. But if you have an object named
Client and a table named CLI_DETAILS then you'll have problems, the
same for fields and properties name, but that's why I said that this
approach is better for a greenfield project with ORM in mind.

Check the example on my second e-mail, there's no DB details there,
the logical relationship between Category and SubInformation is very
clear, we don't use any strings so it's all checked at compile-time
and we don't need two objects. Then again, this is just another
approach option, an has it's own benefits and costs.

Cheers,
Rafael.

Luis Abreu

unread,
Nov 28, 2008, 5:12:59 AM11/28/08
to sharp-arc...@googlegroups.com
> Ok, agreed on DDD :)

good :)


> As for POCO, well, not linking the domain objects library to some
> external framework references is something I don't believe we can ever
> achieve, unless we're working with very simple objects. The need for
> validation is the first thing that comes to my mind, and things like
> DomainSignature, for example, are very useful and I think that
> outweighs the problems of referring a few external libraries.

validation is easy achievable with inversion of control, though most
guys will not go that far. As I've said, it all depends on what you
want: if you don't mind having those dependencies, then there's
nothing wrong with the attributes :)


> On the other hand, adding another class to do the mapping obscures the
> code, makes us search basic informations about our model in two
> different places, and that's something that I qualify as much more
> important than linking one or two external libraries, and in the case
> o ActiveRecord you don't need to reference NHibernate's.

I disagree. Persistence information is a detail...important, but not a
domain detail, and that's why I don't think it's important that you
don't put that kind of info on the domain. There's a detail here: you
keep mentioning databases, but is that really important when you
tjhink about domain driven design? I know there are several guys out
there which don't use databases for storing the domain objects and
I'll be trying to use that approach in my work. to make that happen, I
really want my objects to be persistent ignorant and that means no
attributes or any db info on my domain model...


> As for DB implementation details, if you build your objects correctly
> and makes your DB schema comply to your objects structure, not the
> other way around, you won't need to give any details about
> implementation on the attributes, just make explicit the logical
> relationships, which will make the code clearer. For example, if you
> have all your tables named after the objects and all table's fields
> name after your objects properties, them you don't need to specify the
> implementation name in the attributes. But if you have an object named

To me the db is a detail related with storage. I don't really care
about the table structure and I will always build the database from
the object model I have in my domain (not the other way around)...
--
Regards,
Luis Abreu

Rafael

unread,
Nov 28, 2008, 6:25:52 AM11/28/08
to S#arp Architecture
Hi,

Inversion of Control is a good practice, and I would even say a vital
on when working with static languages such as C#, no questions about
it. But, isn't validation part of the domain concerns? For example,
allowing or denying a empty property on an object should be an
explicit on the domain model, don't you think? Of course there are a
lot of other validations, but I consider them domain logic not an
implementation or persistence detail.

As for referring to databases, well, 90% of all domain objects will be
persisted to a RDBMS, so I use it as a reference, but the information
added by the attributes are not exclusive to databases, they express
the logical relationships between objects, it doesn't matter how you
store them. A has-many relationship can be expressed on a database or
a XML file, and I believe it's important to differentiate it from,
let's say, a many-to-many relationship on both scenarios, or even if
you're not persisting them at all.

I think that using domain objects that are too skinny, devoid of all
context, is an error, we need enough information to know how objects
should work (validation included) and how they are connected to others
(logical relationship), and separating these essential pieces of
information just makes it harder to understand them. If these
informations will be used to make the persistence is irrelevant, and
these concerns will be addressed on another part of the system. In the
end we aren't tying domain logic to persistence details, keeping these
two worlds apart as it should be.

Cheers,
Rafael.

DaRage

unread,
Nov 28, 2008, 11:10:07 AM11/28/08
to S#arp Architecture


> Inversion of Control is a good practice, and I would even say a vital
> on when working with static languages such as C#, no questions about
> it. But, isn't validation part of the domain concerns? For example,
> allowing or denying a empty property on an object should be an
> explicit on the domain model, don't you think? Of course there are a
> lot of other validations, but I consider them domain logic not an
> implementation or persistence detail.

Validation is important and is part of the domain knowledge but why
should it be tide to persistence?
I don't understand why castle active record is responsible for both
persistence and validation. I think this is a major design flow and
it's evident in the case of using active record without base class. In
that case you lose all validation support! I think this is bad because
if validation and persistence were kept separate you wouldn't have
such limitation.

> As for referring to databases, well, 90% of all domain objects will be
> persisted to a RDBMS

Not true. I'm working on a project that persists objects remotely
using web services.

> I think that using domain objects that are too skinny, devoid of all
> context, is an error

I agree. POCO is not a goal by itself by a way to achieve domain
purity. but i think for practicle reason we need to use libraries to
perform common tasks needed by the domain such as domain validation,
equality and hash key calculation, etc.

My comment on the whole subject is I think if you're using a database
then mapping to the database has to happen somewhere. in the case of
active record they happen in the domain object which i think is wrong
because of the reasons mentioned already. in the case of fluent
nhibernate it happens outside the domain where they should be and
they're verified at compile time which gives them an advantage over
xml mapping.


Rafael

unread,
Nov 28, 2008, 11:46:04 AM11/28/08
to S#arp Architecture
Hi,

Validation is not tied to Castle ActiveRecord, but I do use another
Castle's component called Validator that's inside the
Castle.Components.Validator namespace. This way you can have
validation without tying it to persistence, and this is the standard
Castle implementation, so it's not a design flaw. A colleague
explained me sometime ago how you can use it to validate forms
decorating DTOs, it was very interesting. Here's the link, but it's in
French :)

http://groups.google.fr/group/parisaltnet/browse_thread/thread/fd11cd2f147df62e

And when I said that 90% of objects were persistent in databases I
meant it as general practice, but I do know that this is not true for
all projects. Most developers work for years and never see a non-RDBMS
persistence strategy, but this is very unlikely within the audience of
this group.

Just to make clear, the actual process of mapping the domain objects
to the database is executed somewhere else, not inside the domain
library. The advantages I see is that with ActiveRecord you just
decorate the object for future use, without the need to use a base
class or alter its behavior, and you don't need and extra class to
understand how your objects work, it's all in one place with the same
amount of external references and with persistence ignorance. XML
configuration is "evil", I won't argue otherwise :)

Cheers,
Rafael.

Luis Abreu

unread,
Nov 28, 2008, 1:30:18 PM11/28/08
to sharp-arc...@googlegroups.com
> Validation is important and is part of the domain knowledge but why
> should it be tide to persistence?
> I don't understand why castle active record is responsible for both
> persistence and validation. I think this is a major design flow and
> it's evident in the case of using active record without base class. In
> that case you lose all validation support! I think this is bad because
> if validation and persistence were kept separate you wouldn't have
> such limitation.


Agreed...that's why I keep insisting in having some sort of base classes on
the domain for validation. I'd prefer a library without any dependencies on
OR/Ms, but again, I'm just giving my opinion...


> > As for referring to databases, well, 90% of all domain objects will
> be
> > persisted to a RDBMS
>
> Not true. I'm working on a project that persists objects remotely
> using web services.

And, as I've said, I've also seen several guys which resort to serialization
to disk with some great results...I do agree that DBs are common though, but
when you think about DDD, they're not that important by themselves...

> I agree. POCO is not a goal by itself by a way to achieve domain
> purity. but i think for practicle reason we need to use libraries to
> perform common tasks needed by the domain such as domain validation,
> equality and hash key calculation, etc.
>
> My comment on the whole subject is I think if you're using a database
> then mapping to the database has to happen somewhere. in the case of
> active record they happen in the domain object which i think is wrong
> because of the reasons mentioned already. in the case of fluent
> nhibernate it happens outside the domain where they should be and
> they're verified at compile time which gives them an advantage over
> xml mapping.
>

Agreed....

Luis

Rafael

unread,
Nov 29, 2008, 9:35:18 AM11/29/08
to S#arp Architecture
Hi Luis,

Why don't you take a look at Castle Validator? It's not tied to
ActiveRecord or any other library, you can use it to validate anything
you want. Take a look at the test case:

http://svn.castleproject.org:8080/svn/castle/trunk/Components/Validator/Castle.Components.Validator.Tests/ContributorsTests/ValidatorContainerInterfaceContributorTestCase.cs

Using it you don't need a base class, have a lot of common validations
out of the box (e-mail, length, not empty, etc) and can create your
own validations extending the base attribute. It's worth a quick peek.

Cheers,
Rafael.

Rafael

unread,
Nov 29, 2008, 9:40:47 AM11/29/08
to S#arp Architecture
Hi,

I forgot to add this link. It's a introduction by Hammet, Castle's
founder and developer of this particular tool.

http://hammett.castleproject.org/?p=114

Cheers,
Rafael.

Luis Abreu

unread,
Nov 29, 2008, 10:42:23 AM11/29/08
to sharp-arc...@googlegroups.com
Hello again.

I'll do that. Thanks.

--
Luis Abreu


> -----Original Message-----
> From: sharp-arc...@googlegroups.com [mailto:sharp-
> archit...@googlegroups.com] On Behalf Of Rafael
> Sent: Saturday, November 29, 2008 2:35 PM
> To: S#arp Architecture
> Subject: Re: Why Fluent NHibernate?
>
>
> No virus found in this incoming message.
> Checked by AVG - http://www.avg.com
> Version: 8.0.176 / Virus Database: 270.9.10/1815 - Release Date: 27-11-
> 2008 09:02

DaRage

unread,
Nov 29, 2008, 11:27:42 PM11/29/08
to S#arp Architecture
Hi Rafael,

Regarding the castle validation being tied to persistence, I relied on
the link you provided which states "Another consequence of not using a
base class is missing validation support.":

http://www.castleproject.org/activerecord/documentation/trunk/advanced/mediator.html

I've never used castle but maybe there is a work around.


> The advantages I see is that with ActiveRecord you just
> decorate the object for future use, without the need to use a base
> class or alter its behavior, and you don't need and extra class to
> understand how your objects work, it's all in one place with the same
> amount of external references and with persistence ignorance.

Well.. they cannot be in the same place and be persistence ignorance
at the same time. that's and oxymoron right?
maybe what you mean to say that it's very cheap and doesn't not
contaminate the domain and at the same time provides a lot of
functionality. That I can buy and maybe use for pracicle reason but
let's agree it's no DDD.



> XML configuration is "evil", I won't argue otherwise :)

I agree and thus is fluent nHibernate.


Rafael

unread,
Nov 30, 2008, 8:04:01 AM11/30/08
to S#arp Architecture
Hi DaRage,

They say that you will loose the validation support in the sense:
validation support out of the box, mixed with your Save, Update, etc.
It seems that the main confusion around this issue is that people
don't know very well how Castle's ActiveRecord works, so I'll try to
structure it a little better.

There are two ways of using it:

1 - ActiveRecord the "Rails way"
In this scenario you build a object that is mapped to the database
through decorating it with attributes and inheriting it from a base
class, like ActiveRecordValidationBase. For example:

using Castle.ActiveRecord;
using Castle.Components.Validator;

[ActiveRecord]
public class Client : ActiveRecordValidationBase
{
[PrimaryKey]
public virtual int ID {get; set;}
[Property, ValidateNonEmpty]
public virtual string Name {get; set;}
}

In this case your Client object will automatically map the properties
ID and Name to a table called Client looking form fields ID and Name.
Besides that, the class Client will have static functions that will
perform persistence operations like Save, Load, etc. So, if you wanna
create a new user in the database, you should do something like:

Client myClient = new Client();
myClient.Name = "My Client's Name";
if (myClient.IsValid)
Client.Save(myClient);

Note that the code is simplified, I didn't want to add transactions
and other details. This approach is much more interesting when working
with Rails, since you can code much less and do much more, without
worrying about types, dozens of libraries, IoC, DI, etc. But that's
not the point here.

Using this approach works, but I was convinced that the Repository
Pattern has a lot of advantages, so we can use Castle's ActiveRecord
to just do the mapping stuff and Castle's Validator to do the
validation work. Notice that I need to import two libraries to make
this work, one for the mapping (Castle.ActiveRecord) and another for
the validation (Castle.Components.Validator), so they aren't
connected.

2 - Using Castle's ActiveRecord with the Repository Pattern

The code would be something like this:

using Castle.ActiveRecord;
using Castle.Components.Validator;

[ActiveRecord]
public class Client
{
[PrimaryKey]
public virtual int ID {get; set;}
[Property, ValidateNonEmpty]
public virtual string Name {get; set;}
}

Hum, that's almost the same thing, but now I'm not inheriting it from
ActiveRecordValidationBase, so I don't have the Save, Update, etc,
methods. All this work has to be done somewhere else, the Client class
is POCO, it's just an object with two properties and no other special
behavior. The attributes don't change it's behavior, they are just
markers to be used by the persistence routines, that should be in
another assembly. This makes the class "de facto" persistence
ignorant, but this information is very useful for the understanding of
the domain, and it doesn't make any difference if I'm persisting this
object to a database or a XML file, a primary key will be the unique
identifier of the object in both cases, and that's domain information.
The same goes for the non-empty Name property.

Now, if I want to Save and Validate a new client, I need to do
something like this:

Client myClient = new Client();
myClient.Name = "My Client's Name";

IValidatorRunner runner = new ValidatorRunner(new
CachedValidationRegistry());
if (runner.IsValid(myClient))
ActiveRecordMediator<Client>.Save(myClient);

In this case we need two distinct objects to make the persistence and
the validation, but now my Client is POCO and I can have the
advantages of the Repository Pattern, like having a database
repository and a XML repository, both using the same Client class. In
this case I also need to explicitly call the validation through the
use IValidatorRunner, but that's exactly the point, not having
validation tied to persistence. If I want, I can use the validation
logic without any persistence.

The biggest advantage when using Castle's stuff, is that you don't
need a separated mapping class and you have all relevant domain
information in just one place, without the need to use a base class
and with persistence ignorance, since the mapping attributes just
decorate the object. As I said before, I'm not throwing rocks at
Fluent NHibernate, it's a very good tool, but I can't see any big
advantage when compared to Castle, and I can't see what make this
approach non-DDD.

Cheers,
Rafael.

Billy

unread,
Nov 30, 2008, 11:14:32 AM11/30/08
to S#arp Architecture
Thank you for this interesting conversation. There are certainly pros
and cons to any approach, many of which have been explained well
here. If it helps to bring this to a conclusion, we will be staying
with Fluent NHibernate and NHibernate.Validator for the anticipated
1.0 release of S#arp Architecture.

Thank you again for all the input concerning alternative approaches.

Billy

DaRage

unread,
Nov 30, 2008, 11:47:53 AM11/30/08
to S#arp Architecture
Thanks Rafael for explaining how Castle work. Now I see how validation
can be used separately from persistence.

The example that show is trivial and it doesn't show how persistence
"knowing" the class is. here is an example i found on the web about
using castle on-to-many mapping:

[HasMany(typeof(Post), Table="PostTable", ColumnKey="blog_id")]

This is clearly not persistence ignorance and shows the advantage of
pulling the mapping outside the class with fluent nHibernate.

Rafael

unread,
Nov 30, 2008, 12:00:00 PM11/30/08
to S#arp Architecture
Hi DaRage,

Yes, this example is not persistence ignorant, but all the "bad
information" can be excluded if your database objects comply to your
domain objects names. In this example, if your Post object is
persisted in a table named "Post" and you have the BelongsTo(typeof
(Blog)), than you don't need to explicitly name the columns and tables
your using, and the declaration goes back to:

[HasMany(typeof(Post)]

No strings, no persistence information, and you know exactly what's
the logical relationship between the two objects. As I've noted in
another post, this approach works better when your database complies
to the objects, and not the other way around. For legacy databases, or
new ones that do not comply to your domain, Fluent NHibernate might be
a better option. Besides that, IMHO, Castle's components are more
mature than then new libraries.

Cheers,
Rafael.

DaRage

unread,
Nov 30, 2008, 4:05:39 PM11/30/08
to S#arp Architecture
If your model has to match the database then it's not independent of
the database. it's actually very tightly coupled to the database
because if you change the model you have to change the database and
vice versa. in the case of fluent nHibernate that's not the case
because the mapping is done outside the model.

Rafael

unread,
Nov 30, 2008, 4:39:07 PM11/30/08
to S#arp Architecture
Yes, you're right, if don't wanna a string in your code you have to
keep the database name the same as your objects, otherwise you'll need
to put the actual name of the table in a string somewhere. It's
possible to change ActiveRecord's parameters and attributes from other
layers to overcome these problems, but then again you'll have 2 places
to look when you change the model, and that's exactly what I want to
avoid. I'd rather force the database to be comply to my model.

Cheers.
Rafael.

DaRage

unread,
Nov 30, 2008, 7:10:42 PM11/30/08
to S#arp Architecture
Even when have a database that complies with the model, even when you
have mapping without strings you still have tight coupling between the
database and model.

Attributes like HasMany are database specific and should not appear in
the model, that's of course if you're doing DDD. A domain model should
only be described with domain patterns like aggregates,
specifications, services, repositories, etc. and not database
terminology like primary keys, has-many relations, etc.
Reply all
Reply to author
Forward
0 new messages