moleskine di un programmatore

Appunti di viaggio tra bit e byte

January 2008 - Posts

Un piccolo softwarino in aggiunta.... adattato da noi :D
Prendendo spunto dall'attualità ecco la nuova frontiera dello sviluppo software ;D

il negozio di senatori
NHibernate, Lazy, Sessioni e Cache

Appunto di viaggio: applicazione Asp.Net con AjaxToolkit ed NHibernate 1.2. Il domain model è mappato in modalità lazy per massimizzare le performance.

Il lato presentation dell'applicativo fa uso intensivo di UpdatePanel che al bisogno completano l'interfaccia  utente con delle chiamate in background; per gestire le chiamate asincrone l'entity principale del documento resta in session e viene riagganciata alla session (session-per-request in un modulo http) per fare in modo che i proxy creati per la gestione delle entity lazy possano funzionare correttamente.

Tutto fila liscio finchè non mi accorgo che in caso di edit di una entity, alcune proprietà non vengono salvate su db. Le provo tutte fino a che (disperato) scarico i sorgenti di NHibernate, compilata nuova e inizio il debug per capire dove sta l'inghippo.

Il problema è proprio nel fatto di riassociare l'entity alla session di pagina (page_load) che  poi verrà usata per fare anche la transazione di salvataggio; il fatto di riassociare l'entity alla session con ISession.Lock(entity, LockMode.none) causa l'inserimento nella cache di sessione dello stato ATTUALE dell'entity (che è in session) falsando il controllo di dirty check che esegue NHibernate per decidere se e cosa aggiornare sul db.

PANICO!!!!

Lavoro da consegnare e una tonnellata di entity da dover fixare... Due ore su google per cercare soluzioni ma non ne trovo nessuna indolore.
Provo con un interceptor, ma il check di dirty si basa comunque sullo stato al momento della reattach alla session e quindi niente; provo a vedere se vale la pena di scrivermi un persister custom ma a naso non mi garantisce il risultato..... mumble.. mumble...

IDEA!

Visto che voglio forzare il salvataggio indipendentemente dallo stato della cache la soluzione più immediata è quella di un bel Session.Evict(entity) prima di fare la SaveOrUpdate(entity).

Risultato: 0 mapping modificati, 0 dataentry modificati, 1 riga di codice in più sul gestore del salvataggio nella classe base da cui derivano tutte le form. Soluzione poco elegante ma di impatto zero. Per stavolta è andata bene :D

Prxm.Greetings