Propendo anche io per le chiavi Guid, che hanno un ulteriore vantaggio, durante la Save, nhibernate non deve per forza fare l'insert fisico dell'oggetto nella tabella per prendere l'id. In questo caso puoi lasciare comunque generare a lui il guid, cosi se hai un guid.null sai che non è mai stato inserito in sessione, e puio usare il saveorUpdate. Altrimenti come dice mauro lo metti tu a mano, ma poi devi tenere traccia se l'oggetto è persistente o meno, per capire se chiamare save o update.
In generale tutte le identità autogenerate dal db possono in generale causare problemi.
Cmq io eviterei sessioni che durano *giorni*, puoi avere un impatto sulla memoria disarmante, visto che ogni ISession di nhibernate si tiene in memoria tutti gli oggetti che ha salvato/caricato/reidtratato.
alk.
--Blog Eng: http://www.codewrecks.com/blogBlog Ita: http://blogs.ugidotnet.org/rgmTwitter: http://twitter.com/alkampfer
Chiavi autogenerate forzano l'ORM a fare insert immediatamente appena chiami il Save, questo ti può dare problemi se ad esempoi hai scelto il FlushMode=Never, perchè in realtà quando inserisci il flush lo fa subito. Un esempio concreto
Supponiamo che in una app web hai l'utente che naviga un wizard di X pagine, in ogniuna mette dei dati, alla fine decide se commitare tutto o no. Un possibile approccio è quello di dire, ad ogni step io prendo gli oggetti, li salvo in session ma con flushmode = never alla fine decido se fare il flush. Purtroppo non funziona. (Cmq ci sono modi molto migliori di fare questo senza toccare il flush mode :) Era solo un piccolo esempio. )
Un altro problema è, supponiamo di ammettere che il db possa essere disconnesso, ad esempio ho un tablet con cui l'utente viaggia in giro per un capannone con la wirless, avere la possibilità di dire, io intanto le entità le salvo, ma poi il flush lo faccio solo quando ho la rete e sono convinto che tutto vada può essere un vantaggio.
Per il discorso autocad il fatto è questo, una session di nhibernte tiene tutti gli oggetti in memoria nella sua Identity Map Interna, per questa ragione non è sempre consigliabile tenere la sessione viva per moltissimo tempo, devi fare una stima. Se vuoi tenere la sessione sempre attiva allora dovresti magari fare evict degli oggetti che non usi più. Se invece sai che non hai problemi di memoria puoi tenere sempre la stessa ma fai attenzione che
1) Se in una transazione per qualche ragione fai il rollback la sessione va disposata, non la puoi più usare.
2) Se in una operazione di salvataggio/inserimento o flush nhibernate fa eccezione, anche se tu la gestisci la sessione va disposata :)
Ciao alk,
Gian Maria Ricci: Per il discorso autocad il fatto è questo, una session di nhibernte tiene tutti gli oggetti in memoria nella sua Identity Map Interna, per questa ragione non è sempre consigliabile tenere la sessione viva per moltissimo tempo, devi fare una stima. Se vuoi tenere la sessione sempre attiva allora dovresti magari fare evict degli oggetti che non usi più. Se invece sai che non hai problemi di memoria puoi tenere sempre la stessa ma fai attenzione che 1) Se in una transazione per qualche ragione fai il rollback la sessione va disposata, non la puoi più usare. 2) Se in una operazione di salvataggio/inserimento o flush nhibernate fa eccezione, anche se tu la gestisci la sessione va disposata :)
Mumble mumble... facciamo un discorso "generale" (ma sempre aderente al mio caso). So che non ho problemi di memoria, quindi posso tranquillamente tenere in memoria tutti gli oggetti. Il problema dispose/salvataggio (insomma, del Dispose della session) non mi spaventa, nel senso che lo scenario non presenta troppi problemi da questo punto di vista. Il problema principale però sta nel fatto che:
- è difficile modellare il mio dominio in maniera che possa essere simile a una descrizione secondo il modello E-R
- la persistenza non è su un DB
- la chiave va generata alla *creazione* dell'entità e non al suo salvataggio e deve essere valida anche se l'entità è transiente
Quindi alla fine, mutuando un po' qui e un po' lì, dando uno sguardo a NHibernate e seguento attentamente i vostri consigli sono riuscito a impostare qualcosa di decente. Ora, devo capire bene il discorso dynamic proxy (qualche link?) ma credo di essere sulla buona strada.
Ciao e grazie,
Giulio
--
In questo caso la chiave guid, generata da te è la cosa migliore, devi solo capire quali oggetti sono stati salvati e quali no per sapere se chiamare save o Update.
Per il discorso dynamic proxy ti consiglio questo link http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx si tratta di una libreria per la generazione dinamica di codice in grado di generare proxy per le tue interfacce, viene usata da nhibernate per fare il lazy load, ma considera che non sei bloccato solo ad usare castle, ma puoi usare anche altre librerie perchè dalle ultimke versioni di nhibernate è configurabile.
petrux:alkampfer wrote: > In questo caso la chiave guid, generata da te è la cosa migliore, devi > solo capire quali oggetti sono stati salvati e quali no per sapere se > chiamare save o Update. Uhm... e se non avessi la persistenza su un db?
Se non hai la persistenza su db, non hai problemi, nel senso che quegli oggetti non li passi a nhibernate e magari li salvi da un'altra parte con altre tecniche etc etc. Alla fine se un oggetto non viene persistito non ha nemmeno molto senso che abbia un campo Id, la sua identità può essere garantita dal framework.
Alk.
Puoi quindi lavorare con id assegnati dal software e usare i guid per non avere problemi. A quel punto gli oggetti che vanno nel db non hanno problemi, gli metti l'id assigned, quelli che non vuoi mettere nel db e vuoi salvare da altre parti non hai comunque porblemi perchè serializzando e deserializzando ti ritrovi l'id li, probabilmente è la soluzione più semplice :)