Qualche giorno fa mi sono trovato di fronte ad una eccezione sollevata da NHibernate che mi ha fatto prima dannare e poi riflettere.
Cercando di farla breve, mentre recuperavo da db un oggetto di tipo A veniva sollevata un eccezione riguardante un oggetto di tipo B che non aveva legami con nessuna delle altre entità del domain model.
In effetti la causa non era riconducibile all'oggetto A, ma dipendeva dal fatto che avevo istanziato un oggetto di tipo B (quindi ancora transiente) e lo avevo associato ad un terzo oggetto, che a sua volta aveva aggiunto quell'oggetto B alla bag di un quarto (!) oggetto di tipo ancora diverso.
Quell'oggetto transiente, quindi, veniva persistito in modo del tutto spontaneo da parte di NH nel momento in cui eseguivo la Commit della transazione aperta per recuperare tutt'altri dati non direttamente correlati.
Insomma quell'oggetto veniva persistito prima ancora di essere validato e prima ancora che io avessi deciso di volerlo persistere!
Inutile dire che sono rimasto piuttosto perlesso da questo comportamento. Nulla da obiettare, intendiamoci, perchè nella documentazione viene spiegato abbastanza bene come funziona la modalità automatica (FlushMode.Auto) di flushing, ma personalmente avrei condiviso maggiormente un FlushMode.Never by default, proprio perchè un comportamento simile potrebbe davvero rivelarsi molto pericoloso.
Detto questo rimane da decidere come utilizzarlo, questo meccanismo di flushing. FlushMode.Auto condiziona davvero non poco la scrittura del codice ai livelli superiori, annullando IMHO il concetto di Persistence Ignorance che NHibernate riesce ad offrire così bene, e quindi, escludendo anche FlushMode.Commit che riduce ma non annulla il problema, rimane FlushMode.Never.
Quindi forse l'unica scelta potrebbe essere proprio la FlushMode.Never, che ci ridà il controllo su quello che succede nel contesto di persistenza, lasciando decidere a noi quando e cosa persistere.