Mapping by code

226 views
Skip to first unread message

Fabio Maulo

unread,
Jan 13, 2010, 1:08:56 AM1/13/10
to nhibernate-...@googlegroups.com
Hi team.

I would like to have a code re-view of my last post and a constructive feedback
http://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api.html

The post, and overall the code, is basically an example about how implement a custom API to create mappings by code.
That is an invitation to everybody want create his own API and even an invitation for FNH team to use the Hbm* classes instead generate XML.

That said, seeing how things are going in each framework, NH needs its own mapping-by-code.
Two matters here:
1) API definition
2) usage of Hbm* or directly create metadata (classes of namespace NHibernate.Mapping)

What is clear is that our implementation will supports anything supported by XML and, probably, we will improve some of actual "conventions-interceptors" (as, for instance, INamingStrategy & Co. ).

--
Fabio Maulo

James Gregory

unread,
Jan 13, 2010, 4:37:08 AM1/13/10
to nhibernate-...@googlegroups.com
I have two large concerns about migrating FNH to use the Hbm* classes.

Firstly, a lot of the feedback the user gets (and thus FNH) is from the XSD validation errors. Last time I experimented with the Hbm* classes there was little-to-no validation on the actual model, leading only to NullReferenceException's at runtime if the user forgets to map an Id or anything like that. This was a big stumbling block. It certainly could be avoided by us building a validation layer prior to passing to NHibernate, but that's even more work on-top of the migration.

Secondly, last time we attempted to use the Hbm* classes we had an absolute nightmare dealing with changing versions of NHibernate. The model was changing between minor versions, and that meant we not only needed to recompile FNH with the new NH but we had to make code changes too; this made extremely hard to support multiple versions at the same time. The XML on the other hand is generally unchanging, or at least completely backwards compatible, so when a new NH version comes out there's nothing todo apart from rebuild the solution.

If you can show me how those points have changed since I last tried it, then I'll be happy to use it.

As for the API, well, I'm biased. :)

Fabio Maulo

unread,
Jan 13, 2010, 8:42:29 AM1/13/10
to nhibernate-...@googlegroups.com
I said :
"an invitation for FNH team to use the Hbm* classes instead generate XML"
The invitation can be accepted or refused, that is a FNH's team choice.

The discussion here is about what we will do *for* NHibernate3.0.
--
Fabio Maulo

James Gregory

unread,
Jan 13, 2010, 8:46:22 AM1/13/10
to nhibernate-...@googlegroups.com
Of course, and it's an invitation I'd like to accept, but only if my previous concerns are no longer relevant. 

Richard Brown (gmail)

unread,
Jan 13, 2010, 8:50:27 AM1/13/10
to nhibernate-...@googlegroups.com
Hi Fabio,
 
I've only had a quick look, but it looks OK to me (I realise it's not fluent-style, but I'm not sure it's worth our time trying to make it fluent ... especially when the FNH guys do it so well).  I like the idea of being able to use classes like that (and any subsequent conventions) in the NH tests.
 
Regarding point 2, Is there any advantage in changing it to target NHibernate.Mapping over Hbm*?  (I'm guessing no?)
 
 
James,
 
One of the features I love about FNH is the AutoPersistenceModel.WriteMappingsTo(...) to allow me to see the generated xml ... if you were to move to using the Hbm* classes, I don't think it's just errors you'd want to see, but (somehow) the mapping even when there were no errors.
 
 

Sent: Wednesday, January 13, 2010 1:46 PM
Subject: Re: [nhibernate-development] Mapping by code

Of course, and it's an invitation I'd like to accept, but only if my previous concerns are no longer relevant. 

Fabio Maulo

unread,
Jan 13, 2010, 9:02:48 AM1/13/10
to nhibernate-...@googlegroups.com
The advantage, may be, is performance and the possibility of a good refactoring about metadata-creation/modification.
The usage of metadata will be a big challenge and a lot of work to do.
The usage of Hbm* is more like a joke and will give us the ability to see the XML.

In both cases what we should talk about is the API:
what I have used in the post is a "hbm-xml-mimic" style and, IMO, it is the best way for various reasons...

Anything here is a team's decision so, please, take your time and have a look to the code.

2010/1/13 Richard Brown (gmail) <fluk...@googlemail.com>



--
Fabio Maulo

Richard Brown (gmail)

unread,
Jan 13, 2010, 9:08:17 AM1/13/10
to nhibernate-...@googlegroups.com
> The usage of Hbm* is more like a joke and will give us the ability to see the XML.
 
Can we re-serialise the Hbm* classes back into XML?  (If so, then definitely keep using them).
 
 
> In both cases what we should talk about is the API:
>what I have used in the post is a "hbm-xml-mimic" style and, IMO, it is the best way for various reasons...
 
I'm happy with the example shown ... I suspect I'd need to use it in anger for a while to have anything more concrete to say.
 
 

Fabio Maulo

unread,
Jan 13, 2010, 9:14:42 AM1/13/10
to nhibernate-...@googlegroups.com
For sure we can serialize Hbm* to have the XML.
In the code you can see the example in : MapDslTests.CreateXmlDemo.ShowXml()

And this is the result of that mapping (readable as written by hand using NH's conventions):
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="MapDsl" assembly="MapDsl" xmlns="urn:nhibernate-mapping-2.2">
  <class name="Animal">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="Description" />
    <property name="BodyWeight" />
    <many-to-one name="Mother" />
    <many-to-one name="Father" />
    <many-to-one name="Zoo" />
    <property name="SerialNumber" />
    <set name="Offspring" order-by="Father">
      <key column="animal_key" />
      <one-to-many class="Animal" />
    </set>
  </class>
  <joined-subclass name="Reptile" extends="Animal">
    <key column="animal_key" />
    <property name="BodyTemperature" />
  </joined-subclass>
  <joined-subclass name="Lizard" extends="Reptile">
    <key column="reptile_key" />
  </joined-subclass>
  <joined-subclass name="Mammal" extends="Animal">
    <key column="animal_key" />
    <property name="Pregnant" />
    <property name="Birthdate" />
  </joined-subclass>
  <joined-subclass name="DomesticAnimal" extends="Mammal">
    <key column="mammal_key" />
    <many-to-one name="Owner" />
  </joined-subclass>
  <joined-subclass name="Cat" extends="DomesticAnimal">
    <key column="domesticanimal_key" />
  </joined-subclass>
  <joined-subclass name="Dog" extends="DomesticAnimal">
    <key column="domesticanimal_key" />
  </joined-subclass>
  <joined-subclass name="Human" extends="Mammal">
    <key column="mammal_key" />
    <component class="Name" name="Name">
      <property name="First" />
      <property name="Initial" />
      <property name="Last" />
    </component>
    <property name="NickName" />
    <property name="Height" />
    <property name="IntValue" />
    <property name="FloatValue" />
    <property name="BigDecimalValue" />
    <property name="BigIntegerValue" />
    <bag name="Friends">
      <key column="human_key" />
      <many-to-many class="Human" />
    </bag>
    <map name="Family">
      <key column="human_key" />
      <map-key type="String" />
      <many-to-many class="Human" />
    </map>
    <bag name="Pets" inverse="true">
      <key column="human_key" />
      <one-to-many class="DomesticAnimal" />
    </bag>
    <set name="NickNames" lazy="false" sort="natural">
      <key column="human_key" />
      <element type="String" />
    </set>
    <map name="Addresses">
      <key column="human_key" />
      <map-key type="String" />
      <composite-element class="Address">
        <property name="Street" />
        <property name="City" />
        <property name="PostalCode" />
        <property name="Country" />
        <many-to-one name="StateProvince" />
      </composite-element>
    </map>
  </joined-subclass>
  <class name="User">
    <id name="Id">
      <generator class="foreign">
        <param name="property">Human</param>
      </generator>
    </id>
    <property name="UserName" />
    <one-to-one name="Human" constrained="true" />
    <list name="Permissions">
      <key column="user_key" />
      <list-index />
      <element type="String" />
    </list>
  </class>
  <class name="Zoo">
    <id name="Id">
      <generator class="native" />
    </id>
    <discriminator />
    <property name="Name" />
    <property name="Classification" />
    <map name="Mammals">
      <key column="zoo_key" />
      <map-key type="String" />
      <one-to-many class="Mammal" />
    </map>
    <map name="Animals" inverse="true">
      <key column="zoo_key" />
      <map-key type="String" />
      <one-to-many class="Animal" />
    </map>
    <component class="Address" name="Address">
      <property name="Street" />
      <property name="City" />
      <property name="PostalCode" />
      <property name="Country" />
      <many-to-one name="StateProvince" />
    </component>
  </class>
  <subclass name="PettingZoo" extends="Zoo" />
  <class name="StateProvince">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="Name" />
    <property name="IsoCode" />
  </class>
</hibernate-mapping>


2010/1/13 Richard Brown (gmail) <fluk...@googlemail.com>
> The usage of Hbm* is more like a joke and will give us the ability to see the XML.
 



--
Fabio Maulo

Ayende Rahien

unread,
Jan 13, 2010, 9:19:18 AM1/13/10
to nhibernate-...@googlegroups.com
As long as we are doing things this way, can we keep those classes around in the session factory?
It would be very useful to be able to access them at some later point in life.

Fabio Maulo

unread,
Jan 13, 2010, 9:23:50 AM1/13/10
to nhibernate-...@googlegroups.com
The session-factory is using Metadata classes to generate Persisters and so on...
You know... the session-factory is immutable (about mappings)... to change a mapping would mean change a lot of things created at session-factory-build (all queries for example).

2010/1/13 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Jan 13, 2010, 9:26:27 AM1/13/10
to nhibernate-...@googlegroups.com
Oh, I don't want to modify them, I just want to be able to inspect them.

Fabio Maulo

unread,
Jan 13, 2010, 9:47:39 AM1/13/10
to nhibernate-...@googlegroups.com
If needed we can "improve" inspection of Persisters, Tuplizers and so on... btw, the "inspection" and usage of those classes is the main work done by NH ;)

2010/1/13 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Jan 13, 2010, 9:50:03 AM1/13/10
to nhibernate-...@googlegroups.com
That really depend on who is doing the inspecting.
I know that _I_ can't really read the persisters/tuplizers and understand what is going on the same way I can from reading the mapping files.
The idea of keeping that information around, especially since it is going to be as a set of lightweight classes, means that we can regenerate the mapping files and show the user what he fed into NH.

Fabio Maulo

unread,
Jan 13, 2010, 9:59:14 AM1/13/10
to nhibernate-...@googlegroups.com
aaaaaaaaaaahhhh you mean for NH-Prof.
Well... after BuildSessionFactory you can throw the Configuration instance.
In that example I'm using Hbm* as information holders.
Perhaps you can ask to the user to give the Configuration instance to NH-Prof and you can keep those classes inside NH-Prof.

2010/1/13 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Jan 13, 2010, 10:10:42 AM1/13/10
to nhibernate-...@googlegroups.com
There was a reason that I didn't specify NH Prof out front, it is because I don't think that this is just as useful for users without it.

Fabio Maulo

unread,
Jan 13, 2010, 10:18:39 AM1/13/10
to nhibernate-...@googlegroups.com
IMO, there is no reason to keep alive the mapping after configuration... btw we will see.
Now my interest is about the "mapping by code" stuff.

About "keep alive the mapping" you can analyse this matter right now because we are using Hbm* in NH3.0

2010/1/13 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Steve Wagner

unread,
Jan 14, 2010, 4:56:08 AM1/14/10
to nhibernate-...@googlegroups.com
Hi Fabio, i am not a team member but i will also give you my opinion.

I like it!

* It dose not use the context less fluent classes (which meens
map.Class(..).Property(...).Property(...))
* It is clean and not polluted with Of,For and all this useless words
* It follows the XML mapping name schema, which is my main criticism on
FluentNhiberate because its much harder to use for beginners and i can
not directly infer from NHibernate's documentation to corresponding the
fluent mapping.

-Steve

Fabio Maulo

unread,
Jan 17, 2010, 5:40:06 PM1/17/10
to nhibernate-...@googlegroups.com
Please, I'm needing feed-back coming from code-review.

Try to think at it as a possible mapping-by-code solution for NH3.0.
I'm seriously thinking to add it in NH directly.

2010/1/13 Fabio Maulo <fabio...@gmail.com>



--
Fabio Maulo

Stephen Bohlen

unread,
Jan 18, 2010, 10:21:18 AM1/18/10
to nhibernate-...@googlegroups.com
First, some quick impressions:
  • Its conceptually nice to relegate XML mapping to a less-central role within NH (e.g., XML now becomes just ONE of MANY possible 'mapping input syntax forms') so I applaud the effort/intent
  • Decoupling mapping + config from XML entirely will definitely support many more alternate declarative inputs (custom DSL, whatever) in a manner much more flexible than having to depend on XML as an 'intermediate translation layer' for NH to consume mapping/config info
  • I like that the thrust of the syntax more closely parallels the nodes/attributes used in the XML files, making it approachable to existing users of XML mapping files (reasonably shallow learning curve) even as this leads to a fairly verbose API (compared let's say, to something like FNH where 'terse API' was --from my reading-- an implicit design goal)
Next, some more specific feedback/issues/thoughts/concerns we might want to consider (in no particular order):
  • If this API is to become 'authoritative' for mapping, then by extension it clearly needs to completely support all existing 'xml constructs' fully
  • Unlike FNH where the authors have taken the entirely valid approach of "we're releasing with support for the 80% of NH mapping constructs that are most-commonly in use, permitting people to weave in xml-based content for the parts we don't yet support in code, and over time we will evolve to support the remaining 20% edge-cases in the fluent API", IMO for NH this API shouldn't be released into the codebase until it has 100% functional equivalency with each and every existing XML construct and doesn't rely on intermingling xml for any of its needs.
  • Obviously as an existing proof-of-concept this isn't yet done but it would seem important before making this the authoritative API to ensure that adequate spikes are done to be certain that for every 'statement' presently possible in XML, there's at least an idea about how to express that in this new API (some of the edge-cases that come to my mind initially are things like the <database-object> elements, stored procedures, filter statements, where statements, etc. that aren't immediately obvious from the sample code in the blog post re: how they would be addressed -- basically the entire category of things presently definable in XML that aren't necessarily *directly* about mapping entities per-se but that are about caching directives, other DB elements, etc.)
  • We need to ensure that adequate consideration is given to how this API would express things that aren't immediately possible to state as lambda's without some 'tricks' via reflection, etc.  For example, this kind of statement from the sample code...
map.Class<Animal, long>(animal => animal.Id, id => id.Generator = Generators.Native, rc =>
...won't work where the POID is actually not a public property of the Animal class but is instead a private field and of course the statement (animal => animal._persistentId, ...  won't compile b/c the private field _persistentId is not visible to intellisense (or more importantly, the compiler!).  To be sure, there are 'tricks' to get around this lambda limitation, but I recommend that we should consider carefully what this will look like when invoked via this API to be sure its as clear as the public-property-based mappings shown in the sample code.
  • How does moving this fluent-API into the role of 'primary' mapping API affect NH's 'parity' with Hibernate?  Is it possible that Hibernate might get a future feature that would want to be ported to NH but we would find that this (hypothetical) new feature isn't expressible in the new fluent API?  Obviously nobody can predict the future, but the move to this API as 'primary' mapping API would seem to represent a digression from NH's close parity with H which may impact the ease with which future features can be ported from H to NH.  This new fluent API might very well be a useful/valuable digression (and obviously there are already OTHER features that have been added to NH that take advantage of the .NET platform and don't have an allegory in Hibernate so diverting from exact parity with H isn't without precedent), but IMO we should carefully consider its potential future impact on porting H features to NH before we decide to 'deprecate' XML as the primary/core mapping API.
In short: I like the approach, think it will be quite valuable and helpful to anyone trying to write inputs to the NH mapping/config API in the future, but recommend that we consider the above issues/thoughts before introducing this API as a 'replacement' for the primacy of the xml API in the project.

HTH,

Steve Bohlen
sbo...@gmail.com
http://blog.unhandled-exceptions.com
http://twitter.com/sbohlen

Fabio Maulo

unread,
Jan 18, 2010, 11:20:23 AM1/18/10
to nhibernate-...@googlegroups.com
Some of XML "statements" are actually supported by our configuration through metadata directly instead a mapping API.
The first implemented was exactly for <database-object>:
conf.AddAuxiliaryDatabaseObject(IAuxiliaryDatabaseObject obj)

btw I think we will include everything in the API:
map.DatabaseObject....
map.TypeDef
map.FilterDef
and so on.

About private fields and access="none" and "columnName": in these cases I don't think we having any kind of alternative than use a string.

On the other end, for the <id> for example, in NH you may have neither a property nor a field. The possible overload are:

Class with public POID property getter
void Class<TEntity>(Expression<Func<TEntity, object>> idProperty, Action<IIdMapper> idMapping, Action<IClassMapper<TEntity>> classMapping) where TEntity : class;

Class with private POID field:
void Class<TEntity>(string idFieldName, Action<IIdMapper> idMapping, Action<IClassMapper<TEntity>> classMapping) where TEntity : class;
 
Class with neither a property nor a field
void Class<TEntity, TPoid>(Action<IIdMapper> idMapping,  Action<IClassMapper<TEntity>> classMapping) where TEntity : class;
(note: in this last case the TPoid is enough to create the mapping).

About NH and Hb:
"Stay closer" does not mean "do the same or less", we can do something more because we are using .NET and, at the same time, in some cases we must do less because we are using .NET.
I don't think we will have something like Hibernate.Annotation nor Hibernate.EntityManager. In Hibernate they are thinking in their ecosystem and, unfortunately, without any kind of communication with us (this is not the same of Spring.NET). 
The "mapping source" is only a little detail in NH-Core, what is important is that we are supporting same mappings features or more (and believe me we are supporting more mappings-features in various cases).

2010/1/18 Stephen Bohlen <sbo...@gmail.com>



--
Fabio Maulo

Stephen Bohlen

unread,
Jan 18, 2010, 11:37:45 AM1/18/10
to nhibernate-...@googlegroups.com
Agree on all counts; sounds like you have already thought through much of what I was mentioning.  Just trying to ensure that we're thinking about all the impacts before making the proposed change(s) :D

It seems to me that the suggested approaches for mapping POID have all the bases covered well (via strings for the private fieldname, etc.).  In FNH this was accomplished with a Reveal.Property<T>(...) method (http://wiki.fluentnhibernate.org/Fluent_mapping_private_properties lays out their provided choices).  That wiki entry does a great job of laying out the pros and cons of the various approaches and I was wondering if your thoughts were more along those lines (reflection helper class) or the string-literal approach.

re: NH and Hb 'correlation', I completely agree w your observation here: some divergence cannot be avoided and other divergence is in NH's best interests to improve the project for .NET (and this proposed API is perhaps one of those 'valuable' divergences!).

Fabio Maulo

unread,
Jan 18, 2010, 12:04:33 PM1/18/10
to nhibernate-...@googlegroups.com
hmmmm... to add something in the domain-entity only because NH needs is not something that I like so much.
I like POCOs with "muy poco" ("muy poco" is spanish and in italian it is "molto poco").

2010/1/18 Stephen Bohlen <sbo...@gmail.com>



--
Fabio Maulo

Erich Eichinger

unread,
Jan 18, 2010, 12:10:47 PM1/18/10
to nhibernate-...@googlegroups.com
Why not offer both choices to the user? Some may prefer resilience to refactoring over purity

-Erich

----- Opprinnelig melding -----
Fra: Fabio Maulo <fabio...@gmail.com>
Sendt: Montag, 18. Jänner 2010 18:04
Til: nhibernate-...@googlegroups.com
Emne: Re: [nhibernate-development] Re: Mapping by code

2010/1/18 Stephen Bohlen <sbo...@gmail.com>

>>> - Its conceptually nice to relegate XML mapping to a less-central


>>> role within NH (e.g., XML now becomes just ONE of MANY possible 'mapping
>>> input syntax forms') so I applaud the effort/intent

>>> - Decoupling mapping + config from XML entirely will definitely


>>> support many more alternate declarative inputs (custom DSL, whatever) in a
>>> manner much more flexible than having to depend on XML as an 'intermediate
>>> translation layer' for NH to consume mapping/config info

>>> - I like that the thrust of the syntax more closely parallels the


>>> nodes/attributes used in the XML files, making it approachable to existing
>>> users of XML mapping files (reasonably shallow learning curve) even as this
>>> leads to a fairly verbose API (compared let's say, to something like FNH
>>> where 'terse API' was --from my reading-- an implicit design goal)
>>>
>>> Next, some more specific feedback/issues/thoughts/concerns we might want
>>> to consider (in no particular order):
>>>

>>> - If this API is to become 'authoritative' for mapping, then by


>>> extension it clearly needs to completely support all existing 'xml
>>> constructs' fully

>>> - Unlike FNH where the authors have taken the entirely valid approach


>>> of "we're releasing with support for the 80% of NH mapping constructs that
>>> are most-commonly in use, permitting people to weave in xml-based content
>>> for the parts we don't yet support in code, and over time we will evolve to
>>> support the remaining 20% edge-cases in the fluent API", IMO for NH this API
>>> shouldn't be released into the codebase until it has 100% functional
>>> equivalency with each and every existing XML construct and doesn't rely on
>>> intermingling xml for any of its needs.

>>> - Obviously as an existing proof-of-concept this isn't yet done but


>>> it would seem important before making this the authoritative API to ensure
>>> that adequate spikes are done to be certain that for every 'statement'
>>> presently possible in XML, there's at least an idea about how to express
>>> that in this new API (some of the edge-cases that come to my mind initially
>>> are things like the <database-object> elements, stored procedures, filter
>>> statements, where statements, etc. that aren't immediately obvious from the
>>> sample code in the blog post re: how they would be addressed -- basically
>>> the entire category of things presently definable in XML that aren't
>>> necessarily *directly* about mapping entities per-se but that are about
>>> caching directives, other DB elements, etc.)

>>> - We need to ensure that adequate consideration is given to how this


>>> API would express things that aren't immediately possible to state as
>>> lambda's without some 'tricks' via reflection, etc. For example, this kind
>>> of statement from the sample code...
>>>
>>> map.Class<Animal, long>(animal => animal.Id, id => id.Generator = Generators.Native, rc =>
>>>
>>> ...won't work where the POID is actually not a public property of the
>>> Animal class but is instead a private field and of course the statement
>>> (animal => animal._persistentId, ... won't compile b/c the private field
>>> _persistentId is not visible to intellisense (or more importantly, the
>>> compiler!). To be sure, there are 'tricks' to get around this lambda
>>> limitation, but I recommend that we should consider carefully what this will
>>> look like when invoked via this API to be sure its as clear as the
>>> public-property-based mappings shown in the sample code.
>>>

>>> - How does moving this fluent-API into the role of 'primary' mapping

Fabio Maulo

unread,
Jan 18, 2010, 12:17:03 PM1/18/10
to nhibernate-...@googlegroups.com
2010/1/18 Erich Eichinger <eeich...@gmail.com>

Why not offer both choices to the user? Some may prefer resilience to refactoring over purity

Possible and we can implements it but does not mean that I should like it.
In NH there are a lot of thing I would remove... 
the first, for example, is <composite-id> without a specific class for ID,
the second is <join> inside Class (ok inside <subclass>)
and there are many others that does not mean I'll remove it. ;)
--
Fabio Maulo

Erich Eichinger

unread,
Jan 18, 2010, 12:21:45 PM1/18/10
to nhibernate-...@googlegroups.com
I didn't say *I* like it

----- Opprinnelig melding -----
Fra: Fabio Maulo <fabio...@gmail.com>

Sendt: Montag, 18. Jänner 2010 18:17
Til: nhibernate-...@googlegroups.com
Emne: Re: Re: [nhibernate-development] Re: Mapping by code

Stephen Bohlen

unread,
Jan 18, 2010, 12:22:10 PM1/18/10
to nhibernate-...@googlegroups.com
I think that FNH wiki post I linked does an excellent job of outlining the tradeoffs in the various (general) approaches.  I'm not necessarily suggesting that (like FNH chose) NH should support all approaches equally by any means, just that its a good summary of the relative pros and cons of each approach for consideration re: how best to address the impedence between Expressions and private members.

Fabio Maulo

unread,
Jan 18, 2010, 12:44:32 PM1/18/10
to nhibernate-...@googlegroups.com
ok.. ok.. they are some details we can talk about during/after implementation.
I'll wait some others few days, for feedback, before start the implementation in NH3.0.

2010/1/18 Stephen Bohlen <sbo...@gmail.com>



--
Fabio Maulo

Tobes

unread,
Jan 18, 2010, 2:59:29 PM1/18/10
to nhibernate-development
I like the idea of writing mappings in code for sure. And, your code
sample certainly looks very readable to me :) Nice.

Agree with James in that good validation up front would be a huge
bonus.

The fact that it mirrors the XML is a very good thing from a
learnability point of view. It's DRY too (one set of terms for 2
mapping approaches).

I imagine you could use an XSLT translation to convert XML mappings to
this new code version. All the existing documentation could then be
updated to show samples for both approaches. This would make for a
smoother documentation effort :) I'm also thinking about NHibernate in
Action 2, if anyone ever gets it started :S

I also like the idea that this could be a useful core feature, upon
which the community to build their own DSLs.

My 2p worth.

On Jan 13, 6:08 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> Hi team.
>
> I would like to have a code re-view of my last post and

> a constructive feedbackhttp://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api....
>
> <http://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api....>The


> post, and overall the code, is basically an example about how implement a
> custom API to create mappings by code.
> That is an invitation to everybody want create his own API and even an
> invitation for FNH team to use the Hbm* classes instead generate XML.
>
> That said, seeing how things are going in each framework, NH needs its own m
> apping-by-code.
> Two matters here:
> 1) API definition
> 2) usage of Hbm* or directly create metadata (classes of namespace
> NHibernate.Mapping)
>
> What is clear is that our implementation will supports anything supported by
> XML and, probably, we will improve some of actual "conventions-interceptors"

> (as, for instance, INamingStrategy & Co. ).
>
> --
> Fabio Maulo

Steve Strong

unread,
Jan 19, 2010, 3:20:49 AM1/19/10
to nhibernate-...@googlegroups.com
That's a pretty comprehensive answer!  I can't think of anything else to add over what you've already said - I think an API for creating the mappings as a core part of NH would be great, and I also agree that keeping the syntax similar to the current XML eases the learning curve and also makes porting from XML to code pretty simple.  If other want some different representation (FNH, for example), they now have a canonical API that they can talk to under the covers, rather than having to generate xml as they do today.

I don't have major concerns about the deviation from Hibernate - it's certainly something that we should bear in mind, but I can't imagine anything that Hibernate are likely to do wouldn't map to this new API - anything they add is likely to be configured through XML (I don't see that going away any time soon), and since the proposed API matches the XML structure quite closely, I can't see that we'll come across anything insurmountable.

Cheers,

Steve

Jason Dentler

unread,
Feb 4, 2010, 4:42:57 PM2/4/10
to nhibernate-development
Hi guys & gals (maybe? probably not)

I don't want to mention this for two reasons:
#1 - I really like this idea and don't want to be responsible if you
decide to kill it.
#2 - I am fully aware of the contempt that C# coders have for less
developed .NET languages on issues like this.

A lot of this syntax simply won't work in the current version of
VB.NET.

Thanks,
Jason

On Jan 19, 2:20 am, Steve Strong <srstr...@gmail.com> wrote:
> That's a pretty comprehensive answer!  I can't think of anything else to
> add over what you've already said - I think an API for creating the
> mappings as a core part of NH would be great, and I also agree that
> keeping the syntax similar to the current XML eases the learning curve
> and also makes porting from XML to code pretty simple.  If other want
> some different representation (FNH, for example), they now have a
> canonical API that they can talk to under the covers, rather than having
> to generate xml as they do today.
>
> I don't have major concerns about the deviation from Hibernate - it's
> certainly something that we should bear in mind, but I can't imagine
> anything that Hibernate are likely to do wouldn't map to this new API -
> anything they add is likely to be configured through XML (I don't see
> that going away any time soon), and since the proposed API matches the
> XML structure quite closely, I can't see that we'll come across anything
> insurmountable.
>
> Cheers,
>
> Steve
>
> On 18/01/2010 16:21, Stephen Bohlen wrote:
>
>
>
> > First, some quick impressions:
>

> >     * Its conceptually nice to relegate XML mapping to a less-central


> >       role within NH (e.g., XML now becomes just ONE of MANY possible
> >       'mapping input syntax forms') so I applaud the effort/intent

> >     * Decoupling mapping + config from XML entirely will definitely


> >       support many more alternate declarative inputs (custom DSL,
> >       whatever) in a manner much more flexible than having to depend
> >       on XML as an 'intermediate translation layer' for NH to consume
> >       mapping/config info

> >     * I like that the thrust of the syntax more closely parallels the


> >       nodes/attributes used in the XML files, making it approachable
> >       to existing users of XML mapping files (reasonably shallow
> >       learning curve) even as this leads to a fairly verbose API
> >       (compared let's say, to something like FNH where 'terse API' was
> >       --from my reading-- an implicit design goal)
>
> > Next, some more specific feedback/issues/thoughts/concerns we might
> > want to consider (in no particular order):
>

> >     * If this API is to become 'authoritative' for mapping, then by


> >       extension it clearly needs to completely support all existing
> >       'xml constructs' fully

> >     * Unlike FNH where the authors have taken the entirely valid


> >       approach of "we're releasing with support for the 80% of NH
> >       mapping constructs that are most-commonly in use, permitting
> >       people to weave in xml-based content for the parts we don't yet
> >       support in code, and over time we will evolve to support the
> >       remaining 20% edge-cases in the fluent API", IMO for NH this API
> >       shouldn't be released into the codebase until it has 100%
> >       functional equivalency with each and every existing XML
> >       construct and doesn't rely on intermingling xml for any of its
> >       needs.

> >     * Obviously as an existing proof-of-concept this isn't yet done


> >       but it would seem important before making this the authoritative
> >       API to ensure that adequate spikes are done to be certain that
> >       for every 'statement' presently possible in XML, there's at
> >       least an idea about how to express that in this new API (some of
> >       the edge-cases that come to my mind initially are things like
> >       the <database-object> elements, stored procedures, filter
> >       statements, where statements, etc. that aren't immediately
> >       obvious from the sample code in the blog post re: how they would
> >       be addressed -- basically the entire category of things
> >       presently definable in XML that aren't necessarily *directly*
> >       about mapping entities per-se but that are about caching
> >       directives, other DB elements, etc.)

> >     * We need to ensure that adequate consideration is given to how


> >       this API would express things that aren't immediately possible
> >       to state as lambda's without some 'tricks' via reflection, etc.
> >       For example, this kind of statement from the sample code...
>

> > map.Class<Animal,long>(animal =>  animal.Id, id =>  id.Generator =Generators.Native, rc =>


> > ...won't work where the POID is actually not a public property of the
> > Animal class but is instead a private field and of course the
> > statement (animal => animal._persistentId, ...  won't compile b/c the
> > private field _persistentId is not visible to intellisense (or more
> > importantly, the compiler!).  To be sure, there are 'tricks' to get
> > around this lambda limitation, but I recommend that we should consider
> > carefully what this will look like when invoked via this API to be
> > sure its as clear as the public-property-based mappings shown in the
> > sample code.
>

> >     * How does moving this fluent-API into the role of 'primary'


> >       mapping API affect NH's 'parity' with Hibernate?  Is it possible
> >       that Hibernate might get a future feature that would want to be
> >       ported to NH but we would find that this (hypothetical) new
> >       feature isn't expressible in the new fluent API?  Obviously
> >       nobody can predict the future, but the move to this API as
> >       'primary' mapping API would seem to represent a digression from
> >       NH's close parity with H which may impact the ease with which
> >       future features can be ported from H to NH.  This new fluent API
> >       might very well be a useful/valuable digression (and obviously
> >       there are already OTHER features that have been added to NH that
> >       take advantage of the .NET platform and don't have an allegory
> >       in Hibernate so diverting from exact parity with H isn't without
> >       precedent), but IMO we should carefully consider its potential
> >       future impact on porting H features to NH before we decide to
> >       'deprecate' XML as the primary/core mapping API.
>
> > In short: I like the approach, think it will be quite valuable and
> > helpful to anyone trying to write inputs to the NH mapping/config API
> > in the future, but recommend that we consider the above
> > issues/thoughts before introducing this API as a 'replacement' for the
> > primacy of the xml API in the project.
>
> > HTH,
>
> > Steve Bohlen

> > sboh...@gmail.com <mailto:sboh...@gmail.com>
> >http://blog.unhandled-exceptions.com
> >http://twitter.com/sbohlen


>
> > On Sun, Jan 17, 2010 at 5:40 PM, Fabio Maulo <fabioma...@gmail.com
> > <mailto:fabioma...@gmail.com>> wrote:
>
> >     Please, I'm needing feed-back coming from code-review.
>
> >     Try to think at it as a possible mapping-by-code solution for NH3.0.
> >     I'm seriously thinking to add it in NH directly.
>

> >     2010/1/13 Fabio Maulo <fabioma...@gmail.com
> >     <mailto:fabioma...@gmail.com>>


>
> >         Hi team.
>
> >         I would like to have a code re-view of my last post and
> >         a constructive feedback

> >        http://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api....

Fabio Maulo

unread,
Feb 4, 2010, 10:06:02 PM2/4/10
to nhibernate-...@googlegroups.com
Don't worry... VB.NET will evolve or will die (as Delphi).

2010/2/4 Jason Dentler <jasond...@gmail.com>



--
Fabio Maulo

Craig van Nieuwkerk

unread,
Feb 4, 2010, 10:10:10 PM2/4/10
to nhibernate-...@googlegroups.com
> Don't worry... VB.NET will evolve or will die (as Delphi).
>

Ouch, I wouldn't say that in the Delphi newsgroups. They still think
this internet thing won't catch on!

Craig

Fabio Maulo

unread,
Feb 4, 2010, 10:45:40 PM2/4/10
to nhibernate-...@googlegroups.com
I'm an old Delphian, don't worry... btw I can distinguish between something alive and something dead. 

2010/2/5 Craig van Nieuwkerk <cra...@gmail.com>



--
Fabio Maulo

Stephen Bohlen

unread,
Feb 5, 2010, 7:44:27 AM2/5/10
to nhibernate-...@googlegroups.com
I was under the (general) impression that the next version of VB.NET (to ship with the 4.0 framework) is supposed to offer significantly better 'semantic parity' with C# (e.g., any construct you can assemble in C# will have some correlated statement in VB.NET).

The grand "two primary .NET languages, each with divergent strengths and weaknesses" experiment has been acknowledged to be largely a failure for the reason you are pointing out and more and so there is an explicit push with .NET 4.0 to bring the languages back into semantic near-parity (with the probable exception of C# likely *never* getting XML-literals added to it...thank god!)

While this won't resolve the issues you're point out for those remaining in .NET 3.5, this parity *should* permit those that are willing to go to .NET 4.0 to accomplish much of what's shown here (though with an entirely different syntax, of course). [note that I haven't verified that statement so its entirely possible that you can't construct much of this even in the forthcoming VB.NET 10]

After all, if the premise of "right language for the right job" has any traction at all in .NET then just as MS wants me to add a VB.NET project to my otherwise entirely C# solution in order to manipulate XML literals b/c "that language is best for that job", I'm not certain that its all that bad to say to a VB.NET developer that they should add a C# project to their solution to generate NH mappings because "that's the language that's best for that job" :)

I think its pretty clear from watching Microsoft's actions (vs. listening to their marketing words) that while both C# and VB.NET are perhaps "first-class CLR languages", its also the case that C# is "first among equals" within MS and thus I think a C#-leaning API for this is perfectly acceptable to pursue even as it might leave VB.NET-only developers with some difficulties adopting it until such time as the VB.NET language team finds a way to plug the 'gaps' that exist between it and C#.

Just my two cents.

Steve Bohlen
sbo...@gmail.com
http://blog.unhandled-exceptions.com
http://twitter.com/sbohlen

Diego Mijelshon

unread,
Feb 5, 2010, 10:18:48 AM2/5/10
to nhibernate-development
Steve, Jason,

Just to throw a little more gasoline in the fire... ;-)
Do you know of ANY popular .NET library that's written in VB.NET?
NHibernate... no. Castle... no. Log4net... no. NUnit... no. Automapper... no. RhinoMocks... no. I could go on.

The thing is, VB.NET was *NEVER* a first class citizen in the .NET world, and it will never be.
While supporting it is always good, the biggest effort that's worth is not using VB reserved words.

   Diego

Ayende Rahien

unread,
Feb 5, 2010, 10:22:37 AM2/5/10
to nhibernate-...@googlegroups.com
Why limit it to libraries?
I think that the only popular _codebase_ is Dot Net Nuke.

Fabio Maulo

unread,
Feb 5, 2010, 10:23:09 AM2/5/10
to nhibernate-...@googlegroups.com
This thread is becoming something else than the title... I would like to see some other kind of feedback.

2010/2/5 Diego Mijelshon <di...@mijelshon.com.ar>



--
Fabio Maulo

Jason Dentler

unread,
Feb 5, 2010, 4:33:09 PM2/5/10
to nhibernate-...@googlegroups.com
Sorry to derail the conversation. Like I said, I didn't want to bring it up.

Fabio Maulo

unread,
Feb 6, 2010, 8:39:06 AM2/6/10
to nhibernate-...@googlegroups.com
Hi all.
I'm going to begin the implementation of "Loquacious mapping" in the trunk.
- API proposed in my blog (generics and strongly typed)
- *Mapper implementation as studied in ConfORM (namespaces ConfOrm.NH and ConfOrm.Mappers ), neither generic nor strongly typed.

Thoughts ?

2010/1/13 Fabio Maulo <fabio...@gmail.com>
Hi team.

I would like to have a code re-view of my last post and a constructive feedback

The post, and overall the code, is basically an example about how implement a custom API to create mappings by code.
That is an invitation to everybody want create his own API and even an invitation for FNH team to use the Hbm* classes instead generate XML.

That said, seeing how things are going in each framework, NH needs its own mapping-by-code.
Two matters here:
1) API definition
2) usage of Hbm* or directly create metadata (classes of namespace NHibernate.Mapping)

What is clear is that our implementation will supports anything supported by XML and, probably, we will improve some of actual "conventions-interceptors" (as, for instance, INamingStrategy & Co. ).

--
Fabio Maulo




--
Fabio Maulo

sbohlen

unread,
Feb 6, 2010, 9:22:34 AM2/6/10
to nhibernate-development
As nobody provided any realistic reason *not* to proceed as generally
outlined, I suggest this proceed as planned taking into account the
comments/suggestions made here (with the possible exception of the
tangential thread about "make sure this works in VB.NET" ;)

-Steve B.

On Feb 6, 8:39 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> Hi all.
> I'm going to begin the implementation of "Loquacious mapping" in the trunk.
> - API proposed in my blog (generics and strongly typed)
> - *Mapper implementation as studied in ConfORM (namespaces ConfOrm.NH
> and ConfOrm.Mappers ), neither generic nor strongly typed.
>
> Thoughts ?
>

> 2010/1/13 Fabio Maulo <fabioma...@gmail.com>


>
>
>
> > Hi team.
>
> > I would like to have a code re-view of my last post and
> > a constructive feedback

> >http://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api....
>
> > <http://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api....>The

Richard Brown (gmail)

unread,
Feb 6, 2010, 2:14:32 PM2/6/10
to nhibernate-development
+1

I like the idea of having this out-the-box, and available for use in tests
too.

--------------------------------------------------
From: "sbohlen" <sbo...@gmail.com>
Sent: Saturday, February 06, 2010 2:22 PM
To: "nhibernate-development" <nhibernate-...@googlegroups.com>
Subject: [nhibernate-development] Re: Mapping by code

Reply all
Reply to author
Forward
0 new messages