﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>&gt; does not perform things as you expect
  
  
NHibernate's behavior is well documented and has the extension points to change if you need it.
  
Use collection filters for doing that work.
  
You need to understand that in multi threaded world, there is no such thing as the correct answer, only correct at a given time.
  
That is why NHibernate support the notion of optimistic and pessimistic concurrency.
  
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment33</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment33</guid><pubDate>Wed, 01 Oct 2008 08:08:43 GMT</pubDate></item><item><title>liviu commented on Hibernating Rhinos #9 - Application Architecture</title><description>Hi Ayende,
  
  
I agree, the 25 points list not to write your own ORM are valid. But, is it not more frustrating using another framework ( i am not "blaming" Hibernate) that does not perform things as you expect (need)? Trying to tweak something bigger than you written by others that is in continous change...? Nhibernate touches all 25 points you mentioned, but doesn't handle them perfectly.
  
  
Achieving ORM independence is impossible. I was cheating a little when i show myself "mad" that you seem to favor NHibernate in the design.
  
Because all the 25 points are implemented more or less in different ORMs, and some things are really different, and you just cannot escape that without writing a big wrapper for every persistence method.
  
  
No ORM is perfect, but this is just because ORMs are not trying to solve the HARD problems, but just the many EASY ONES.
  
Persistence is very tightly related to logic of the model. This may seem strange but i give you an example:
  
  
a) Lazy loading. I have entity A with a collection of B.  Imagine that for each A i have ~ 5000 B. I am in UI, I load A but i wanted to optimize that so I don't load B collection yet. The B collection loads lazy when it is accessed, but let say it is loaded 5 seconds after I load A. But what if another user updated B collection? It is a problem if I have an aggregate in A,   A.SumB = SUM(B), because i will load a different collection and the sum will be wrong. The solution is that i have to recalculate the SUM on the client side each time I load B collection. 
  
If i want to cheat and have the sum calculated in the database with a trigger, I have still to detect that A has changed after i lazy load B collection and refrech A.SumB.
  
What is here tricky is that i cannot cheat and optimize my aggregate calculation only when B items are added or deleted. I have to explicitily calculate the FULL sum on LOAD, after lazy LOAD.
  
It is a waste to calculate the sum again if i don;t lazy load B collection, so I am bound when doing model logic from persistence and retrieval strategies.
  
  
The scenario is more funny if i do some sort of paging on the lazy loaded collection.
  
  
Another thing are rules. Imagine i have some business rule on A that depends on what is inside my B collection. If i want to check it on client side, so that the user does not do 10 operations, saves and get an error, that is not enough. I have a snapshot of data. So i have to check the rule also when saving data, in transaction, because B can change....so I depend upon persistence ....
  
  
I personally am working just on a thing like that. An ORM that is aware of the model fields and relations but also ON LOGIC. Because if i don't want my model to know about persistence, than a persistence layer must know about some LOGIC rules in the model.
  
  
  
  
  
  
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment32</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment32</guid><pubDate>Wed, 01 Oct 2008 07:37:29 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>@liviu,
  
There is no such thing as ISet
&lt;t in the framework (which I consider a shame).
  
As for the rest, feel free not to use NHibernate, but read this first:
  
[ayende.com/.../...urOwnObjectRelationalMapper.aspx](http://ayende.com/Blog/archive/2006/05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx)&gt;</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment31</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment31</guid><pubDate>Wed, 01 Oct 2008 01:22:58 GMT</pubDate></item><item><title>liviu commented on Hibernating Rhinos #9 - Application Architecture</title><description>...status....to Tobin Harris...
  
googling for "automatic dirty checking" or "transactional write-behind"..700 results...working....
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment30</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment30</guid><pubDate>Tue, 30 Sep 2008 20:27:15 GMT</pubDate></item><item><title>Tobin Harris commented on Hibernating Rhinos #9 - Application Architecture</title><description>@liviu
  
  
NHIbernate came out of Beta in 2005, there's good documentation, tons of forum posts, sites, blog posts and books (if you include Hibernate books). Plus you can browse the source to see what's going on :)  
  
  
But, I agree it's still not perfect, but we're getting there :)
  
  
I'd be surprised if there's no documentation or blog posts about object tracking - have you searched for "automatic dirty checking" or  "transactional write-behind"?
  
  
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment29</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment29</guid><pubDate>Tue, 30 Sep 2008 20:02:30 GMT</pubDate></item><item><title>Toloma&amp;#252;s commented on Hibernating Rhinos #9 - Application Architecture</title><description>Thanks for the nice overview.
  
  
Any reason why you put the IRepository in the persistance assembly and not in the domain assembly?
  
  
Tolomaüs.
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment28</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment28</guid><pubDate>Tue, 30 Sep 2008 19:05:08 GMT</pubDate></item><item><title>liviu commented on Hibernating Rhinos #9 - Application Architecture</title><description>Ayende,
  
Ok, but why not ISet
&lt;t and HashSet
&lt;t?
  
  
I work for a company that develops enterprise software in the spagetti code way, antipatterns championship way.
  
Many times i encounter situations when some kind of changes, optimizations are to be done in the whole application.
  
Because things were not abstracted enough, it is always a pain for  the developers and QA to correct old mistakes and guarantee a deliverable version...
  
  
For example: the type of PKs, some numeric usertypes precision and size, how incremental fetch is implemented, how certain roundings happen for financial calculations, etc
  
  
With Nhibernate i have  a problem: why do i have to pass an xml?
  
Why it is not better to say: Hibernate map this TYPE t and do not try to find it by a string later...nhibernate proxies my objects, takes bad dicisions in my opinion for object tracking, but yet, has no decent documentation how to override that...
  
I wrote a simple ORM mapper in 2 weeks. I prefer to write my 10% solution instead using undocumented Open source code for that exact 10%.
  
  
  
  
  
  
&gt;</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment27</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment27</guid><pubDate>Tue, 30 Sep 2008 16:55:06 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>liviu,
  
Iesi.Collection has no association to NHibernate.
  
.Net doesn't have an ISet/Set implemention, so we need to go to Iesi for that.
  
If you consider that and virtual properties a violation of POCO, you may do so. I find this appropriate and acceptable
  
  
As for the mapping, there are many strategies to deal with that, ranging from plugins to R# and VS to NHibernate Conventions.
  
  
For the PK, you can hide that if you want. I haven't found a good reason to do so in any of my projects.
  
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment26</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment26</guid><pubDate>Tue, 30 Sep 2008 16:22:04 GMT</pubDate></item><item><title>liviu commented on Hibernating Rhinos #9 - Application Architecture</title><description>Hi Ayende, 
  
it's cool to have a presentation. But, i see that you advocating decoupling, have still added a reference to Iesi.Collections.dll to the model project. That's a bit of cheating. You KNOW you will use NHIBERNATE. The same with all virtual properties in the model, they need to be there in order to have NHibernate instrument the lazy loading...
  
  
Hmm, if it quacks like a NHibernate it must be NHibernate :--).
  
  
What is good design in writing hbml by hand to persist a model?
  
I add a property in the model, oops, i have to change my hbml that sits in another project.
  
  
I would have say it is a good design if: the model would have been taged with some generic persistence attributes that do not depend on any ORM.
  
Based on those attributes the persistence cooking would have been handled by a repository wrapper.
  
  
 I would have been impressed if the primary key would be hidden from the model. If i may choose to implement GUIDs as primary keys, do i have to change the model? or just the persistence model?
  
  
  
I would have been marvled if the persistence layer would be generic, without any assumption about the model persisted.
  
Yet, that is not the case.
  
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment25</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment25</guid><pubDate>Tue, 30 Sep 2008 15:15:56 GMT</pubDate></item><item><title>alberto commented on Hibernating Rhinos #9 - Application Architecture</title><description>Thanks, the automatic persistance part was very clarifying. (I had to watch a couple of times to understand what you meant, though, I might be a little slower than usual today).
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment24</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment24</guid><pubDate>Mon, 29 Sep 2008 18:15:45 GMT</pubDate></item><item><title>Stephen commented on Hibernating Rhinos #9 - Application Architecture</title><description>Sorry I just meant is the future coming from the persistence layer, or is it something that sits on top of the persistence layer.
  
  
But I've just rewatched the part about futures and I see that a future isn't something the persistence layer has to understand, the future will purely just manage deferring and then aggregating the queries inside a transaction..
  
  
ps: I'm just being nosey and I could be wrong in my assumptions!
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment23</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment23</guid><pubDate>Mon, 29 Sep 2008 12:06:57 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Stephen,
  
This is implemented using facilities that the persistence layer gives us. I am not sure what you mean with regards to abstract from it
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment22</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment22</guid><pubDate>Mon, 29 Sep 2008 11:54:40 GMT</pubDate></item><item><title>Stephen commented on Hibernating Rhinos #9 - Application Architecture</title><description>^ trigger is the wrong word, btw is the future thing abstract from the persistence layer? ie - does it just aggregate the 'true calls' and send them to the persistence layer at once when one is first needed - or is it up to the persistence layer to manage how futures are optimized inside a tx?
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment21</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment21</guid><pubDate>Mon, 29 Sep 2008 11:52:54 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Stephen,
  
Yes, that is basically how they work
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment20</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment20</guid><pubDate>Mon, 29 Sep 2008 11:51:45 GMT</pubDate></item><item><title>Stephen commented on Hibernating Rhinos #9 - Application Architecture</title><description>Very cool webcast, its probably really obvious to some people how to seperate layers of an architecture cleanly like this, I'm not a large application dev at all but I've always really worried about how generic you can treat a persistence layer given that you need to give it enough context about what you are trying to do.. talking to it inside a unit of work which is generic enough of a construct that it doesn't damage your business logics (in terms of succinctness and not having to write something thats specific to the persistence type), is a perfect way to give it plenty of context..
  
  
The futures thing is very neat, I take it these work inside a transaction so the first future iterated would trigger all deferred actions inside that transaction?
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment19</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment19</guid><pubDate>Mon, 29 Sep 2008 11:49:08 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>It is there, take a look at FutureQueryOf and FutureValue.
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment18</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment18</guid><pubDate>Mon, 29 Sep 2008 11:47:25 GMT</pubDate></item><item><title>Abrakadabr commented on Hibernating Rhinos #9 - Application Architecture</title><description>Ayende, do you plan to add Future
&lt;t() method to IRepository
&lt;t of Rhino.Commons?
&gt;</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment17</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment17</guid><pubDate>Mon, 29 Sep 2008 11:45:04 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Manuel,
  
The problem is that managing the session at the repository level is removing all the advantages that NHibernate bring to the table. Change tracking, automatic persistence, batching, etc.
  
What you want is to have the session for the entire lifespan of the current request.
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment16</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment16</guid><pubDate>Mon, 29 Sep 2008 05:24:34 GMT</pubDate></item><item><title>Manuel Martone commented on Hibernating Rhinos #9 - Application Architecture</title><description>I really like this web cast, but some little things leave me in a sort of "middle state" not realing very well what just I can imagine: 
  
I think I understood the concept behind futures "delayed" collections, I imagine it acts as a sort of "lazy" object...and this I like, but the last thing I cannot understand at all is, when you say that the session stuff (i.e. Flush, Commit) should be done ath higher level than repository, what if I have to deal with some atomic operations? This should be accomplished however by higher code?
  
Thanks for your work, and maybe I don't understood at all all your english in the webcast, so be patient
  
Ciao
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment15</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment15</guid><pubDate>Sun, 28 Sep 2008 23:29:55 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Yes, that is the idea. In the repository is it to low level, at the entire operation, it works much better.
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment14</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment14</guid><pubDate>Sun, 28 Sep 2008 16:41:05 GMT</pubDate></item><item><title>Jan Van Ryswyck commented on Hibernating Rhinos #9 - Application Architecture</title><description>Oh, I see. Doing this in - e.g. WCF-session-per-request - an operation context is fine, just not in the repository itself?
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment13</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment13</guid><pubDate>Sun, 28 Sep 2008 16:36:10 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>The problem is not the actual calling of Flush or Commit, the problem with that scenario is that you are doing this type of work in too lower layer.
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment12</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment12</guid><pubDate>Sun, 28 Sep 2008 15:22:09 GMT</pubDate></item><item><title>Jan Van Ryswyck commented on Hibernating Rhinos #9 - Application Architecture</title><description>In this webcast, you mentioned that calling session.Flush after a session.Save is a bad thing. What if I'm using TransactionScope instead of NHibernate transactions?
  
  
Thx for your efforts for putting out this webcast!
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment11</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment11</guid><pubDate>Sun, 28 Sep 2008 14:13:19 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Please read this one:
  
[ayende.com/.../Shocking-Rob.aspx](http://ayende.com/Blog/archive/2007/06/20/Shocking-Rob.aspx)</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment10</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment10</guid><pubDate>Sat, 27 Sep 2008 17:08:27 GMT</pubDate></item><item><title>Matthieu commented on Hibernating Rhinos #9 - Application Architecture</title><description>I shoud have said that it's not for all type of applications but only for ones which use a model with a lot of entities with a lot of  associations. 
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment9</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment9</guid><pubDate>Sat, 27 Sep 2008 16:56:05 GMT</pubDate></item><item><title>Matthieu commented on Hibernating Rhinos #9 - Application Architecture</title><description>ok I brought the subject because I saw the code I wonder how the Futures can delayed the SQL. It's delayed because the Session is open and so on.
  
  
Why not? &lt;= for the reasons I explained. Your session is always open, so if you have a complex graph of objects and it's lazy-loaded (and it's often the case with Nhibernate, lazy is set to true by default) you can have a lot of SQL queries executed without be aware of it.
  
  
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment8</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment8</guid><pubDate>Sat, 27 Sep 2008 16:47:51 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>&gt;  I'm not saying that Futures is evil, just that it requires that the Session is open during the whole request, it's not always  desirable ?
  
  
Why not? This is my usual MO
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment7</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment7</guid><pubDate>Sat, 27 Sep 2008 16:37:38 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Matthieu,
  
Discussing of lazy loading is orthogonal to the discussion of futures
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment6</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment6</guid><pubDate>Sat, 27 Sep 2008 16:37:08 GMT</pubDate></item><item><title>Matthieu commented on Hibernating Rhinos #9 - Application Architecture</title><description>"The session is opened for the entire request, including the view" &lt;= ok 
  
  
In your sample if your repository returns a collection of Employee (Future) and the entity Employee has a collection mapped as lazy, for example Adresses
  
  
if you do :
  
foreach(Employee emp in myFutureEmployeeCollection)
  
{
  
     foreach(var address in emp.Adresses)
  
      {
  
         someWork(address.Name) // &lt;= N+1 : one select by adresses collection for each employee
  
      }
  
}
  
  
I'm not saying it's always bad, but if the lazyloading of collection/entities is not carefully explained to developpers you can have trouble here. I prefer to have methods in repository that explicitly stated the level of "loading"
  
  
FindEmployee //lazy loading
  
  
FindEmployeeWithAdress // not lazy laoding
  
  
And so the session is never open in the view. If you get the lazy loaded entities, a lazy exception will be throwed (for the developper I mean, not the user :)
  
  
I'm not saying that Futures is evil, just that it requires that the Session is open during the whole request, it's not always  desirable ?
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment5</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment5</guid><pubDate>Sat, 27 Sep 2008 16:30:11 GMT</pubDate></item><item><title>Ayende Rahien commented on Hibernating Rhinos #9 - Application Architecture</title><description>Igor,
  
Which is why I explicitly stated that this is not DDD
</description><link>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment4</link><guid>http://ayende.com/3613/hibernating-rhinos-9-application-architecture#comment4</guid><pubDate>Sat, 27 Sep 2008 15:52:02 GMT</pubDate></item></channel></rss>