Oggi, dopo un lungo periodo in cui mi sono sempre rifiutato di studiare Nhibernate, il crad è riuscito a convicermi. Personalmente non mi è mai piaciuta l’idea di far fare tutto ad un framework senza avere il controllo su molte cose, ma davanti a fatto compiuto devo alzare le mani. :D (qui il crad se la ride).
Piccola premessa per chi non sa cos’è Nhibernate:
Nhibernate è un porting di una libreria Java Hibernate in ambiente .net. Questa libreria ha il compito di agevolare l’utente nella memorizzazione di informazioni in un Database, evitandoci il “problema” di dover scrivere query e “limitando” il nostro compito nello gestire le sole entity. Da queste parole sembra che faccia tutto lui , beh quasi :P.
Detto questo passiamo alla mia esperienza:
Il primo impatto è stato molto brutto, il passaggio da un sistema “classico” è parecchio brusco ma una volta capito come lavora non è difficile da usare (da quel poco che ho potuto vedere).
Se andiamo a pensare quanto possa essere difficile creare un buon DAL (Data Access Layer), quindi “Lazy Load”, “Unit of Work”, ecc, può venir utile tenere in considerazione Nhibernate.
Premetto che praticamente lo uso solo da un giorno, però ad un primo impatto lo potrei descrivere come molto produttivo.
Gestisce lui lo “Unit of Work”, “Lazy Load”, e inserimenti o modifiche di entity a cascata; basti pensare ad una entity Fattura che ha al suo interno una Entity cliente, passando a Nhibernate l’entity fattura, lui provedderà automaticamente a inserire la fattura e il cliente nel caso non sia presente nel Database mentre in una situazione normale avremmo dovuto creare 2 query, n parametri, interrogare il nostro DataHelper, ecc, ora tutto questo ci viene fatto con un risparmi di risorse incredibile.
Altra bella caratteristica è quella di poter cambiare tipo di database a runtime modificando una righa nel web.config oppure di dire a Nhibernate, “...guarda sono in un’applicazione asp.net usa la cache” e lui lo fa per noi :P
In termini prestazionali non so ancora quanto possa incidere, ma da quanto mi dicono se usato bene è molto performate.
Con questo post non voglio dire che dobbiamo sempre usare Nhibernate o che sia il metodo migliore, ci sono persone più adatte a rispondere a questo tipo di interrogativo (Ricky o Andrea per citarne due :P ) , ma vale la pena di perderci un attimo tempo perchè può venir utile.
Per chi vuole iniziare consiglio il libro in pdf stampabile e scaricabile qui e un tutorial che mostra come iniziare qui.
Successivamente (appena capisco un po’ meglio cosa accade in “background”) posto un codice che mostra come iniziare ad utilizzarlo.
sicuramente solo la persona meno indicata per rispondere a quesiti di architettura.
ma rispondo lo stesso.
non mi piace.
principalmente perche lo trovo troppo verboso come la maggiorparte dei progetti derivati da java.
preferisco la mia (forse perche mia
il progetto è comunque notevole.
ciao marco
Beh di lavoro dietro ne fa sicuramente molto ma non lo conosco ancora bene per poter dire usatelo o non usatelo, ieri lo ho scaricato per la prima volta
Quello che prima facevi in dieci ore con NH lo fai in una, devi solo stare attento nel mapping delle entity.
Cmq ci sono molte persone che lo amano e molte che lo odiano, io sto nel mezzo :P, questo mi fa pensare.
byez
Certo Marco, se hai già realizzato un DAL che includa una UnitOfWork, una IdentityMap, Caching, gestione della concorrenza, persitence by reachability, data mapper, query by example e query object, se gestisci anche i value types, se è cross database, se gestisci l'ereditarietà degli oggetti del tuo domain, se hai lazy loading, eager fetch, ecc.ecc.ecc.... cosa te ne fai di NH?
Modificato da Cradle il 19 luglio 2006 12.33 -
e se alcune di queste funzionalità non ti servono? probabilmente aggiungi qualcosa che non è ottimizzato al 100%.
come in tutti i casi, la giusta via è nel mezzo: NHibernate è un bel pezzo di software, ma non lo userei in tutti i progetti del mondo.
Scusa Daniele, ma francamente non riesco a spiegarmi una cosa.
A prescindere dal fatto che alcune di queste funzionalità sono disattivabili (vedi caching di secondo livello, per dirne una), ma come fanno a non servire? Mi spiego meglio:
se faccio un DomainModel per il programmino della rubrica telefonica sono un folle. Il Domain Model comporta parecchie grane, prima fra tutte il mapping sul DB, quindi lo uso quando la complessità dell'applicazione lo giustifica. Detto questo... cosa non serve?
La Unit Of Work? E come distinguo se un oggetto in memoria è stato modificato o se è stato creato ex novo?
Il lazy load? Così magari tiro su una fattura e mi trovo in memoria mezzo DB.
La identity map? così senza identity map rischio di avere in memoria due istanze differenti di un oggetto che provengono dalla stessa riga del DB.
Quello che voglio dire è che ciò che ho elencato, imho, è una serie di features quasi INDISPENSABILI per un buon DAL. E invece secondo me tanta gente pensa che un DAL sia solo una coppia di query in croce e buonanotte.
Mah... "rischio di trovare qualcosa non ottimizzato al 100%" (parliamone, tra l'altro, con NH hai due livelli di cache), però nell'altro modo rischi di creare un'applicazione piena di bug o comunque poco manutenibile.
Poi magari sbaglio io, eh...
figuriamoci se posso odiare del codice...non odio la mia suocera
è verissimo che ti fa risparmiare del tempo( non nel rapporto 10 : 1 comunque), che è un framework notevole ma devo fare le cose come vuole lui, ma se mi piacesse come propone di farle non ci sarebbe problemi.
è solo che con la marea di codice che ho scritto in due anni, difficilemente faccio un Dal nuovo orami riuso quasi tutto, e il tempo che passo a "mappare" con NHibernate lo posso passare a cambiare il mio Dal, ma non escludo a priori di utilizzarlo.
personalmente preferisco progetti come Linq che hanno un enorme vantaggio rispetto NHibernate possono contare sull'itegrazione con il CLR, il compilatore ecc ecc, poi vediamo se ne esce una valida alternativa.
ciao marco
magari non li avrò tutti, spesso li conosco con altri nomi altri mi sfuggono ma ho quello che serve dove serve
il miò non è un attacco a NHibernate figuriamoci, ho detto che è un progetto notevole, completo e complesso.
è un opinione personale che mi porta a preferire la realizzazione di componenti custom piccoli riutilizzabili facili da mantenere.
il Dal che utilzzo non è lontamente paragonabile a un progetto che nasce con scopi completamente diversi dal mio.
per portare un esempio quando eoni fa ero geometra se si progettava una viletta si pensava hai proprietari a dare la giusta dimensione alle loro apsettative.
bel altro approccio ha un centro commerciale, bel altra complessita ma non è detto piaccia e vada bene a tutti.
tutto quà
ciao marco
perche dici che "nell'altro modo" rischio di avere un applicazione piena di bug?
onestamente se nel mio Dal si verifica un problema (e per fortuna ormai è stabile) so dove mettere nel mani immediatamente, magari per la complessità del progetto NHibernate mi troverei invece a implementare delle sporche scorciatoie in caso non fornisse la giusta flessibilità.
ciao marco
So per certo che alcuni stanno aspettando che pure io scriva qualcosa a riguardo, pertanto lo faccio volentieri, anche se chi mi conosce bene sa già che cosa più o meno andrò a scrivere.
come in tutti i casi, la giusta via è nel mezzo...
Partendo da questa affermazione di Daniele che è esageratamente azzeccata, mi sento di dire che in una discussione sulla leicità nell'utilizzo di un ORM per realizzare applicazioni va fatto un distinguo. Quando si parla di applicazioni web, magari enterprise portal, piuttosto che di applicazioni enterprise, si parla di due tipologie di applicazioni che partono da presupposti diversi e affrontano problematiche differenti.
Nella applicazioni web la necessità di persistere lo stato ha da sempre spinto gli sviluppatori a cercare soluzioni più o meno efficienti in tal senso. Questo aspetto non è assolutamente trascurabile quando si sviluppa l'architettura software di una applicazione web in quanto esso ne limita necessariamente le potenzialità. Del resto nella maggior parte dei casi le applicazioni su web si limitano a pubblicare contenuti piuttosto che ad eseguire elaborazioni non troppo complesse per le quali non è richiesto un regime transazionale come invece avviene nel caso delle applicazioni enterprise. Non ha senso mantenere grossi oggetti persistiti e cachati sulla sessione (con il costo che una cosa del genere può comportare) soprattutto in situazioni soggette ad un volume di traffico e di utenza decisamente alto. Non ha senso impiegare soluzioni quali Unit of Work o mantenere una rappresentazione completa in memoria del dominio applicativo in un contesto dove lo stato dell'applicazione viene azzerato ad ogni richiesta a meno che non vengano utilizzati dei meccanismi di persistenza come la cache. In questi casi la minimalizzazione può garantire una agilità di risposta dell'applicazione che un sistema "troppo gonfio" non è in grado di avere. Ecco allora che "tagliare" l'applicazione in modo preciso porta ad una vantaggio decisivo per può far propendere verso soluzioni diverse da un ORM. In questo senso io stesso preferisco puntare ad architetture mirate per massimizzare le prestazioni.
Le applicazioni enterprise sono caratterizzate invece da una alta complessità elaborativa accompagnata dalla necessità di mantenere attivo un contesto transazionale per garantire il livello di affidabilità richiesto. Questo comporta la presenza di meccanismi di persistenza dello stato quali Unit of Work, Lazy Load e compagnia bella, perchè la complessità elaborativa richiede di dover mantenere in memoria una rappresentazione completa degli oggetti. In un contesto come questo, per esempio, il flush sulla sessione transazionale per eseguire il commit delle modifiche può avere un suo perchè... Nelle applicazioni web direi di no, almeno nella stragrande maggioranza dei casi. Nella progettazione di applicazioni enterprise la complessità va gestita in modo adeguato al fine di garantire un livello di affidabilità e di prestazioni accettabile. Un ORM come NHibernate può permettere di affrontare in modo abbastanza semplice la complessità intrinseca che lo sviluppo di una applicazione di classe enterprise comporta, proponendo tra l'altro meccanismi davvero interessanti per la rappresentazione in-memory dello stato del sistema.
Pertanto penso che per i motivi sopra esposti sia Daniele che Cradle abbiano in parte ragione. In ogni caso ha non senso confondere le capre con i cavoli. Semmai va capito quando un certo tipo di soluzione è applicabile e quando no. Non bisogna partire dal presupposto che una soluzione sia giusta a priori, magari solo perchè è di moda. Le scelte vanno ponderate in relazione alle reali esigenze di disegno e di sviluppo con cui si ha a che fare di volta in volta.
Del resto le applicazioni web ed enterprise si facevano anche prima della comparsa di NHibernate!
Ciao, Ricky.
Cradle wrote:
A prescindere dal fatto che alcune di queste funzionalità sono disattivabili (vedi caching di secondo livello, per dirne una), ma come fanno a non servire?
semplicemente perchè cose come il supporto per più db, il suo linguaggio per query o uno strato di persistenza in un'applicazione web potrebbero solo darti fastidio (cioè, aggiungere funzionalità di cui non hai bisogno). la tipica applicazione web, nel 90% dei casi, non ha bisogno di Unit of Work o persistenza, per il semplice fatto che estrae un po' di dati, li manipola, li mostra a video ed è morta lì la questione.
Il lazy load? Così magari tiro su una fattura e mi trovo in memoria mezzo DB.
beh, credo che qualsiasi sviluppatore un po' meno scemo di uno che smanetta da 5 minuti saprebbe farlo
La identity map? così senza identity map rischio di avere in memoria due istanze differenti di un oggetto che provengono dalla stessa riga del DB.
credo che la risposta di prima potrebbe applicarsi anche qui.
Quello che voglio dire è che ciò che ho elencato, imho, è una serie di features quasi INDISPENSABILI per un buon DAL. E invece secondo me tanta gente pensa che un DAL sia solo una coppia di query in croce e buonanotte.
tanta gente nemmeno sa cos'è un DAL. ma il discorso è che mettendogli in mano una roba tipo nhibernate, non è che migliori le cose, perchè in alcuni scenari aggiungi funzionalità che, semplicemente, imho non servono.
Mah... "rischio di trovare qualcosa non ottimizzato al 100%" (parliamone, tra l'altro, con NH hai due livelli di cache), però nell'altro modo rischi di creare un'applicazione piena di bug o comunque poco manutenibile.
il rischio c'è sempre, nessuno lo mette in dubbio. però ci sono casi in cui ti sta bene guadagnare ogni millisecondo possibile, altri in cui semplicemente la complessità dell'applicazione è bassa e/o hai bisogno di limare ogni angolo possibile, per guadagnare in velocità.
Poi magari sbaglio io, eh...
no, la verità, come già detto, è che dipende. resta un gran bel "pezzo di codice", ma, mi ripeto, non lo vedo come qualcosa da utilizzare sempre ed ovunque.
Intanto una premessa: massimo rispetto per il codice che scrivi, non è che stia dicendo che il tuo DAL fa schifo ed è pieno di errori, eh!
Il discorso che faccio è questo: un DAL non è solo "preparo le query e le eseguo", ma molto di più. Intanto già solo il codice ripetitivo delle query può essere una fonte di bug: meno ne scrivo, meno occasioni ho di sbagliare, soprattutto nell'ambito di una parte dell'applicazione in cui, purtroppo, non si può scrivere codice type safe.
Dicevo... un buon DAL è molto di più; lungi da me voler essere presuntuoso, ho espresso le mie argomentazioni in un post sul mio blog tempo fa, lo trovi qui
http://blogs.ugidotnet.org/crad/archive/2006/04/13/38772.aspx
Poi ovviamente non sto a sindacare su come tu acceda ai dati, ciò che dico è che 1) un motore di persistenza è qualcosa di molto difficile da rifare a mano
2)tutte quelle features non sono degli ammenicoli messi lì perché fa figo, ma sono aspetti quasi necessari (non lo dice Marco De Sanctis, eh, lo dice Martin Fowler).
E alla luce di tutto questo, quindi, uscirsene con "io uso il mio DAL, impiego più tempo a fare i mapping che a riadattare il mio codice" mi sembra un tantinello riduttivo.
Tutto qui :)
Marco.
Mi intrometto all'interessante discussione relativa NHibernate per avere un vostro consiglio dato che siete molto esperti. Dovendo realizzare un'applicazione web con queste caratteristiche:
- Base dati molto complessa e articolata
- Accesso da parte di migliaia di utenti
E' consigliabile l'utilizzo di NHibernate per semplificare lo sviluppo l'aggiornamento dell'applicazione? (magari disabiltando la cache e/o altre funzionalità). Chiedo questo perchè leggendo i vari thread si parla di una sostanziale differenza tra l'utilizzo di NHI per applicazioni enterprise e applicazioni con accesso da parte di molti utenti (mio caso)
Grazie per i suggerimenti!
uscirsene con "io uso il mio DAL, impiego più tempo a fare i mapping che a riadattare il mio codice" mi sembra un tantinello riduttivo.
effettivamente sono stato riduttivo ma non voleva certo ridurre l'importanza del Dal ne di NHibernate.
il senso era più meno questo:
sono due anni che lavoro con il mio solito dal, ho il Lazy Load, Identity Map dove serve, cache e Unit of Work un Provider Model ormai solido utilizzabile con più bd (sybase e SqlServer e oracle anche se è stato usato pochissimo) e altre cosucce, è un sistema snello, facile per me da mantenere e conosco ogni riga.
di certo non volevo ridurre l'importanza di un robusto strato di acceso hai dati, ne muovere critiche ad architetture complesse, non considero ammennicoli nessuna delle cose di cui stiamo parlado ma parti integranti dell'applicazione.
non so se riesco a esprimere il mio pensiero nella sua iterezza, scrivere non è mai stato il mio forte, ma Riccardo ci si è avvicinato molto.
ciao marco
sciamano wrote:
Nessuno interessato alla discussione???
beh, è una discussione vecchia e, soprattutto, se leggi le altre risposte potrai trarre una conclusione da solo
Le ho lette, per questo ho posto la domanda/dubbio!
In un'applicazione web alla quale accedono migliaia di utenti (per fare semplici interrogazioni che vengono visualizzate nelle pagine), NHibernate di presta a questa gestione?
sciamano wrote:
In un'applicazione web alla quale accedono migliaia di utenti (per fare semplici interrogazioni che vengono visualizzate nelle pagine), NHibernate di presta a questa gestione?
io non lo userei mai in un'applicazione web, specie ad alto carico. ma io sono io, altri ti direbbero che puoi farlo tranquillamente
Molto interessante è anche il progetto ActiveRecord di Castle [castleproject.org/index.php/ActiveRecord] che basandosi sempre su NH ne semplifica ancora di piu' l utilizzo (anche se mi sono fermato con un problema di cache)
Carlo
Nessuno di voi ha mai utilizzato Gentle.Net ( http://www.mertner.com/confluence/display/Gentle/Home ) ???
Lo stavo provando ora e non mi sembra malvagio, giudizio di un neofila di .NET e tutto il mondo che ci sta dietro..... se potete darmi lumi vi sarei grato
Carlo
Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.






Stampa
Download


Crad's .NET Blog