Etichette

sabato 10 marzo 2012

Ancora info su Nhibernate

Sempre per la serie :
COLCAZZOCHEFUNZIONA 
mi trovo a scrivere un altro bel Post.
 Lavorando in ambienti  eterogenei e integrando procedure già in essere si trovano sempre mille eccezioni da gestire! Nel mio caso dopo aver scapocciato (Famoso termine informatico!!)  con entity frame  della Microsoft e dopo aver scelto  immediatamente Nhibernate, mi sono trovato di fronte ad altri mille piccoli problemi!!! (La povera esistenza dell'informatico)

Premessa:
ho voluto mappare un db esistente su sqlserver su Nhibernate, tale db ha svariate stored procedure e trigger, per esempio all'insert su una tabella scatta un trigger che fa insert su altre N tabelle...
Bella trovata no?
 Ma che succede?  che quando faccio insert su una tabella parte il count row di SQL che segna N insert e non 1 singolo insert, questo provoca una "famosa" eccezione su NHIBERBATE (Ovviamente per me famosa, visto che ripeto mi ha fatto scapocciare).

NHibernate.AdoNet.TooManyRowsAffectedException 

Cerchiamo di rimanere calmi e vediamo come  ragiona Nhibernate e perché da eccezione:
Nhibernate, segue questo processo: se io sto inserendo  una nuova riga in una tabella e sto inserendo in questa tabella una chiave primaria, si aspetta che ci sia solo una riga inserita,  perché la chiave primaria di solito è univoca e per cui non potrebbe essere altrimenti, se ci fossero piu righe con la stessa chiave primaria, ci sarebbe un bel errore, o di progettazione o del motore sql.

Nel mio caso, però c'è un trigger che fa insert su altre tabelle, per cui non c'è nessuna tipologia di malfunzionamento, anzi è stato progettato per funzionare cosi!!!! (in un altra sede insulteremo i progettisiti!)

Ovviamente chi mi legge è curioso, oppure potrebbe avere avuto  il mio stesso problema ed voler sapere conoscere come ho risolto il mio problema.

Io propongo tre vie:

  1. The attach this  practice
  2. The dirty practice
  3. The good pratice






La prima è  semplice, efficace, e consiste nell'attaccarsi a .... e cambiare progetto o cambiare lavoro!



[

La seconda è la pratica brutale, nel senso che grazie al costrutto, (che tutti conosciamo) try  catch
L'immagine associata alla soluzione è stata censurata
(costrutto applicabile all'intera nostra esistenza) possiamo esattamente catturare questa eccezione e far finta che non sia successo niente, con un unica attenzione: -> Nhibernate è transazionale, per cui se volgiamo che tutto funzioni, dobbiamo forzare il flush dei nostri oggetti, e ancora meglio dopo il flush chiudiamo la sessione con NHibernate, perche altrimenti avendo memorizzato quell'eccezione su quella sessione non vi farà più fare niente, se non delle semplici select.



Terza via  è quella di riscrivere i trigger, poichè ogni trigger puo essere riscritto in modo che dopo essere partito non alteri il row count di MS SQL server.
Come ? ecco il comando:

SET NOCOUNT { ON | OFF } 
ovviamente nel nostro caso è da mettere a OFF!


Vorrete sapere quale scelta è stata fatta per il mio progetto? 
Ovviamente deve rimanere una curiosità!