NHibernate & GetCurrentSession

74 views
Skip to first unread message

Jorge Ramos

unread,
Dec 27, 2007, 8:34:05 AM12/27/07
to NHibernate-Hispano
Buenas!, ayer estuve leyendo un thread (http://groups.google.com.ar/
group/NHibernate-Hispano/browse_thread/thread/
f64854c302ee4667/13298b9b8eaedb8d?#13298b9b8eaedb8d) donde se hablaba
de NHibernate para aplicaciones Web y Escritorio. La idea que se
planteaba era a traves del uso de NHibernate.Context. Ahora bien, el
problema que tengo, es que estuve intentando generar las sesiones a
traves de sessionFactory.GetCurrentSession(), pero termino con una
excepcion con el mensaje "No session bound to the current context".
Estuve viendo en la siguiente url http://www.hibernate.org/42.html, y
hay algo que no me queda en claro y es cuando se abre la sesion, ya
que por lo que entendi, al llamar a este metodo por primera vez, se
estaria abriendo la sesion, no?
En fin, estoy medio confundido, si alguien me puede ayudar a entender
un poco esto, estaria mas que agradecido.
Saludos.

Jorge.

Fabio Maulo

unread,
Dec 28, 2007, 12:37:05 AM12/28/07
to NHibernat...@googlegroups.com
La session la generas siempre vos con algunas de los pattern tipo
Session-per-View, Session-per-Conversation, Unit-of-Work.
Lo que hacen los contexts es mantener la session "viva" en algun lugar
de forma que tus DAOs usen siempre GetCurrentSession si comprometerse
con quien y cuando la session fue generada.

El sessionFactory.GetCurrentSession lo unico que hace es pedirsela al
context... practicamente no la genera.

Lo que deberias estudiar es uno de los patrones
Session-per-Conversation y Unit-of-Work.
Te doy mi receta...
Que el front-end sea WEB o WIN no debería importar mucho (hay cosas
para la cuales si importa pero no me concentro en eso ahora).
Tu front-end debería apoyarse en "algo" que representa el UseCase.
Ejemplo:
EmisionFacturaUseCase
CRUDClienteUseCase
EstadidisticoVentasUseCase

Tus clases de UseCase brindan al front-end todo lo que necesita
exactamente como lo necesita. Es decir que si tenes combos, filtro
pre-fabricados, etc. el UseCase lo debería tener ya disponibles para
ser usados as-is.
El UseCase es quien se encarga de manejar la conversation y brindará
servicios del estilo:
IsDirty
Save
Cancel
.... what ever.....
El IsDirty es bastante simple ya que se puede redireccionar
directamente al IsDirty de la session de NH.
Para el Cancel lo que se hará es un RallBack de la transaction de NH y
un close de la session.
Para el Save se hará el Save o el Update de las entidades, cuando no
fue hecho en cada una de ella mientras la conversación estaba activa,
y luego se hace el commit de la transaction de NH y el close de la
session.

Para el prj WEB tendrás que tener cuidado a lo que pasa cuando el
usuario abandona la sessionWeb mientras que para el prj Win es mas
facil porque, por lo general, coincide con el close de un form.

En todo el chiste quien mantiene e maneja una session de NH es el UseCase.

Es posible que se me escape algo... de ser así alguien mas me vas a
correguir o te volveremos a leer por estos pagos.

Bye.
Fabio Maulo

Gustavo Ringel

unread,
Dec 28, 2007, 1:18:02 AM12/28/07
to NHibernat...@googlegroups.com
Yo creo que hay dos problemas con tneer abierta la session en el form, y si me equivoco entonces corregime.
1) Me obliga a que el cliente sepa que trabaja con NHibernate...lo ideal, a mi entender, seria que el cliente fuera agnostico de esto y solo la logica de negocio manejara la sesion.
 
Dicho esto, esta idea es muy complicada de mantener en winforms sin WCF o Web Services o cualquier tipo de logica distribuida, yo todavia tengo complicaciones con eso.
 
Mi problema es que la aplicacion en que uso NHibernate funciona como kioskos de atencion, en los que el usuario abre un form al comienzo del dia y lo cierra al fin del dia, si es que lo cierra...o sea que no puedo asociar al form la sesion.
 
El problema que tengo alla es que tengo timers para refrescar y por otro lado estan las funciones que hace el usuario...como no puedo tener una sesion abierta 14 horas...entonces
trato de hacer una sesion por solicitud al servidor, funciona bien hasta que en un momento el timer justo cae en el medio de un pedido del usuario...para solucionar esto use tecnicas que harian llorar de dolor al arquitecto mas humilde...pero bueno, si alguien quiere discutir y evangelizarme...estoy dispuesto a detallar mas y estudiar soluciones elegantes, porque hoy en dia mi solucion si bien trabaja no es nada buena.
Gustavo.

Fabio Maulo

unread,
Dec 28, 2007, 9:09:18 AM12/28/07
to NHibernat...@googlegroups.com
El 28/12/07, Gustavo Ringel <gustavo...@gmail.com> escribió:

> Yo creo que hay dos problemas con tneer abierta la session en el form, y si
> me equivoco entonces corregime.
> 1) Me obliga a que el cliente sepa que trabaja con NHibernate...lo ideal, a
> mi entender, seria que el cliente fuera agnostico de esto y solo la logica
> de negocio manejara la sesion.
>

Hola Gustavo.
Tal vez fue un mal entendido pero yo no hablé de tener abierta la
session en el form. Quien se ocupa de la session es la clase de
UseCase.
La referencia al form fue porque, en muchas aplicacciones win, un
UseCase se representa mas sencillamente en un form. No siempre es así.
Hay casos en lo cuales el UseCase se representa en una serie de forms
al estilo wizard, en esos casos el UseCase queda vivo para todos los
forms.

En tu caso me parece que hay que cambiar un poco el patrón y usar el
Disconnect-Reconnect, de la session, el Refresh(object) (todavia no
porté el Merge() porque tengo ante que cambiar los cascades) y mas de
una transaction (Begin-Commit/Rollback) en la misma long conversation.

Bye.
Fabio Maulo

Gustavo Ringel

unread,
Dec 28, 2007, 9:18:33 AM12/28/07
to NHibernat...@googlegroups.com
Ok, comprendido el malentendido.
 
Disconnnect-Reconnect esta en el branch o tengo que bajar el trunk?
suena interesante para el tipo de mi aplicacion. en lugar de cerrar la session al terminar de referirme a la logica de negocio, desconectar la session...
En este caso tengo igualmente que ver si la session dio alguna excepcion y recrearla para que no me de errores al hacer flush verdad?
 
Gracias.
 
Gustavo.

Fabio Maulo

unread,
Dec 28, 2007, 9:42:42 AM12/28/07
to NHibernat...@googlegroups.com
El 28/12/07, Gustavo Ringel <gustavo...@gmail.com> escribió:
> En este caso tengo igualmente que ver si la session dio alguna excepcion y
> recrearla para que no me de errores al hacer flush verdad?
>

Luego de una exception la session va siempre destruida porque queda en
un estado incosistente.
Ojo que en tu caso es fundamental que tus entidades implementen
Equals,GetHashCode y sobre todo que sean versionadas. El Merge()
seguramente sería lo mejor para prevenir exceptions debidos a accesos
concurrentes pero bueno.... aún no está disponible.

Bye.
Fabio Maulo

Gustavo Ringel

unread,
Dec 28, 2007, 9:49:12 AM12/28/07
to NHibernat...@googlegroups.com
Equals y GetHashCode siempre lo mantengo, versionadas te referis a tener un timestamp en la entidad para problemas de concurrencia?
Respecto a Merge cuando lo tengas portado avisame...yo podria evitar todos los lios trabajando WCF o incluso remoting (paso DTO's asi que tengo 0 dramas por la serializacion). El tema es que tengo que dar respuestas en decimas de segundo en el peor caso...no quiero meter mas peso a la aplicacion...
Con NHibemate dependo mucho del cache de segundo nivel para esto...
 
Gustavo.

Carlos Peix

unread,
Dec 28, 2007, 10:13:07 AM12/28/07
to NHibernat...@googlegroups.com
Eeeeeeeeeeeeehhhhhhhhhhhhh, "merge", sera lo que pienso?

Justo en el post anterior estaba pensando en consultar por lo que sigue pero no
quise molestar, ahora si me animo.

Una de las features que mas me gusta de Neo (http://neo.sourceforge.net/, (Erik
Doernenburg de ThoughtWorks y Cia.)) eran los contexts (o sesiones en NH)
anidadas.

El concepto es el siguiente (en terminos de NH ´para facilitar la lectura):
puede iniciarse una sesion en determinado lugar de tu codigo y comenzas a operar
contra ella. Luego, en otro lugar necesitas seguir operando pero no sabes si hay
o no hay sesion iniciada (tranquilos, ya se que esto se puede saber, sigan
leyendo), entonces la inicias de nuevo y haces tus cosas. Asi podria hacerse en
varios niveles. Esa sesion puede abrirse contra el store final (base de datos) o
contra la sesion anterior abierta, una suerte de sesion anidada.

Cuando hacias un commit/flush sobre la sesion anidada, en vez de ir a la base de
datos, empujaba (push) los datos a la sesion padre (esto es el Merge, la palabra
magica). Solo el commit/flush de la sesion abierta contra el data store grababa
los cambios en la base de datos.

La ventaja de esto es que si tenias una falla en la sesion anidada, la
descartabas y listo. No era necesario descartar la sesion externa. Hoy en NH,
cuando tenes una excepcion grabando tenes que descartar la sesion porque el
estado de los objetos (las propiedades) ya es invalido comparado contra lo que
tiene registrado NH.

En Neo esto debe haber sido relativamente facil de implementar ya que el soporte
para las propiedades de los objetos estaba implementado en un DataRow de ADO.

Neo recomendaba iniciar contexts para cada pantalla winforms (por ejemplo), yo
hice algunos helpes para dar soporte a lo que acabo de decir.

Esta idea, que a mi me parecio tan buena en esa epoca, es realmente buena o es
una garantia de problemas, que piensan?

Carlos Peix

ldp

unread,
Dec 29, 2007, 11:02:52 AM12/29/07
to NHibernat...@googlegroups.com
Hola, yo el problema que tuve con tratar de implementar una solución de este tipo (una session para el caso de uso) es que en las aplicaciones de escritorio el usuario podría abrir mas de un form a la vez, y estos forms pueden ser de casos de usos completamente diferentes.
Es algo que se me complico mucho de manejar y termine usando algo mas parecido a Unit of Work, manejando la session para cada interaccion con la base...igual que Gustavo, mi solucion
funciona (aunque aveces tengo problemas de objetos repetidos por no cerrar bien la session) pero definitvamente no me parece una
buena solucion

El día 28/12/07, Fabio Maulo <fabio...@gmail.com> escribió:



--
slds, ldp

Fabio Maulo

unread,
Dec 29, 2007, 12:24:44 PM12/29/07
to NHibernat...@googlegroups.com
El 29/12/07, ldp <lpi...@gmail.com> escribió:

> Hola, yo el problema que tuve con tratar de implementar una solución de este
> tipo (una session para el caso de uso) es que en las aplicaciones de
> escritorio el usuario podría abrir mas de un form a la vez, y estos forms
> pueden ser de casos de usos completamente diferentes.
> Es algo que se me complico mucho de manejar y termine usando algo mas
> parecido a Unit of Work, manejando la

Cual fue la complicación?

Gracias.
Fabio Maulo

ldp

unread,
Dec 30, 2007, 7:19:02 PM12/30/07
to NHibernat...@googlegroups.com
Basicamente el problema era en que momento cerrar la session, porque podia haber dos casos de uso corriendo a la vez y usando la misma session entonces para poder limpiar la cache o  cerrarla dependiamos de que ningun otro caso estuviera usandola, lo que podia llegar a que nunca se limpiara o cerrara.
--
slds, y felicidades a todos

Fabio Maulo

unread,
Dec 30, 2007, 8:50:15 PM12/30/07
to NHibernat...@googlegroups.com
2007/12/30, ldp <lpi...@gmail.com>:

Aaaaah!!
Me pareció raro que te habia dado problemas lo que yo escribí en los
mails anteriores.
En lo que dije yo no hay dos UseCase usando la misma session.
Dos casos de uso significa dos NH.Session abiertas.

Bye.
Fabio Maulo

tala...@hotmail.com

unread,
Jan 3, 2008, 5:45:52 AM1/3/08
to NHibernate-Hispano
Jorge,
Yo tuve las mismas preguntas/duas que vos.
Hasta ahora siempre trabaje NHibernate+ Web y ahi es mas simple el
manejo de las sessiones.

Debido a que no existe una explicacion muy clara de este asunto, ni
tampoco ejemplos completos (winForms + session + concurrencia, etc.)
decide armar un document donde trato de explicarme a mi mismo (for
dummies) y espero que sirve para el resto de los mortales.

En el document (+ejemplo) muestro las distintas tecnicas para manejo
de NHibernate Sessions en Winforms, temas de concurrencia, temas de
DataBinding.
Podes bajar el documento (doc + pdf + vs.net sln) de mi blog :
http://stalamoni.blogspot.com/2007/12/nhibernate-and-winforms-article-1st.html

El ejemplo es bastante basico por ahora pero la idea es ir mejorandolo
a medida que reciba feeback.

Nota: Este es un primer borrador (draft) y espero mejorarlo para
incluir otras preguntas / temas, etc. Cuando el documento+ejemplo este
en un nivel razonable lo publicare en los foros de NHibernate (ingles,
etc).

Saludos,
Sebastian Talamoni


On 27 dic 2007, 14:34, Jorge Ramos <reyazu...@gmail.com> wrote:
> Buenas!, ayer estuve leyendo un thread (http://groups.google.com.ar/
> group/NHibernate-Hispano/browse_thread/thread/
> f64854c302ee4667/13298b9b8eaedb8d?#13298b9b8eaedb8d) donde se hablaba
> de NHibernate para aplicaciones Web y Escritorio. La idea que se
> planteaba era a traves del uso de NHibernate.Context. Ahora bien, el
> problema que tengo, es que estuve intentando generar las sesiones a
> traves de sessionFactory.GetCurrentSession(), pero termino con una
> excepcion con el mensaje "No session bound to the current context".
> Estuve viendo en la siguiente urlhttp://www.hibernate.org/42.html, y

tala...@hotmail.com

unread,
Jan 3, 2008, 7:01:27 AM1/3/08
to NHibernate-Hispano

> > Basicamente el problema era en que momento cerrar la session, porque podia
> > haber dos casos de uso corriendo a la vez y usando la misma session entonces
> > para poder limpiar la cache o cerrarla dependiamos de que
> > ningun otro caso estuviera usandola, lo que podia
> > llegar a que nunca se limpiara o cerrara.


> En lo que dije yo no hay dos UseCase usando la misma session.
> Dos casos de uso significa dos NH.Session abiertas.

Existe, por lo que he podido investigar, un caso adicional al de 1
session x Form (=UseCase).
a) 1 sola session / contexto para ambos procesos (lo basicamente
planteado en el post )
b) Separacion Load / Save : es decir , usar un contexto (session)
para retribuir el object y bindearlo y otro contexto/session para
salvarlo.

Aunque en el ejemplo implemento (para probar) las 2 tecnicas, todavia
no tengo muy claro cuales son las ventajas/desventajas.

Saludos,
Sebastian Talamoni

Fabio Maulo

unread,
Jan 3, 2008, 7:25:26 AM1/3/08
to NHibernat...@googlegroups.com
La desventaja es que los cambios que haces con el Save ante de hacer
el flush no se reflejan en la session en donde cargaste todo. Recuerda
que el "Load" es progresivo cuando usas lazy-loading así si tocas algo
de un obj suyacente es probable que se te genere algun conflicto.

De todas formas muchas gracias por tu contribución y seguí
desarrollando el ejemplo que seguramente sirve.
Es muy importante que empezemos a compartir soluciones que hayamos
encontrado, no importa que sean perfecta o super-reutilizables, lo
importante es compartirla.

Bye.
Fabio Maulo

tala...@hotmail.com

unread,
Jan 3, 2008, 10:18:21 AM1/3/08
to NHibernate-Hispano
Fabio,

Muy interesante tu post y me esta gustando este thread.

> Tu front-end debería apoyarse en "algo" que representa el UseCase.
> Ejemplo:
> EmisionFacturaUseCase
> CRUDClienteUseCase
> EstadidisticoVentasUseCase

Me parece buenisimo usar UseCases como Unit-of-work.
Esta muy bueno el concepto que planteas aunque en la implementacion me
surgen algunas dudas que planteo mas abajo.
Hasta ahora no habia encontrado buenos posts sobre Session-x-
Conversation en WinForms (el UseCase lo permite) y este me encanto.

En el ejemplo que estoy armando(*) uso una clase Repository (determina
el contexto,IDisposable, etc) que es parecido a tu approach SALVO que
es realidad es generico y no tiene NADA de especifico como si lo
tienen tus UseCases (me gusta el hecho que en el UseCase es mas
especifico y podes encapsular mas logica de negocio sobre esa
operacion). Me interesaria combinar ambos casos : UseCases como una
clase derivada de Repository. Voy a investigar un poco el tema...



Duda #1 : Relacion entre UseCase y DAO
-------------------------------------------
Algunos UseCases, como EmisionFacturaUseCase, estan claros pero no me
es facil ver cual el limite entre el UseCase y los DAO.

En tu lista veo CRUDClientesUseCase y "creo" (corregime si me
equivoco) que no es muy bueno UseCases a ese nivel. Es decir, en tu
receta vos crearias "siempre" un UseCase por cada "view" en el UI.
Para las operaciones CRUD me parece un poco "exagerado". En mi
opinion, los UseCases no deberian ser creados para casos simples de
CRUD sino mas bien para poder combinar operaciones en un mismo
contexto.

Imaginate que si necesito hacer un Insert de un nuevo cliente dentro
del NuevaFacturaUseCase se complicarian las cosas. Si cada CRUD tiene
su UseCase tambien es complicado enmarcar 2 UseCases juntos: ejemplo
agregar 2 root objects no relacionados entre si (usando misma session
+ misma transaction). Como solucionas este tema?

Ejemplo de como crear un Repository que expone los DAO:
using (Repository repository = new Repository())
{
customer = repository.CustomerDAO.Fetch(testCustomerID);



> Tus clases de UseCase brindan al front-end todo lo que necesita
> exactamente como lo necesita.
>Es decir que si tenes combos, filtro
> pre-fabricados, etc. el UseCase lo debería tener ya disponibles para
> ser usados as-is.

Duda #2: No todo debe/puede estar pre-pensado.
-----------------------------------------------

A veces esto que propones es complicado, especialmente con thick/rich-
client.

Lo que vos planteas en este punto es que el UseCase directamente pasa
a ser un "servicio" donde todo esta predefinido. Existen algunos casos
donde esto resulta no solo demasiado trabajo pero tambien redundante.
Si para cada caso de consulta (filtros, sorting, etc) uno crea un
servicio al final terminamos con un API de servicios enorme. Ademas no
solo importa la innecesaria exposicion sino ademas la combinacion de
consultas ( Clientes where Pais = 2 AND Categoria == 3).

CustomersDAO.GetAll()
CustomersDAO.GetAllPorPais(int paisID)
etc.

Llega un momento donde necesitamos usar hql o ICriteria para
simplificar el API, no?
Ejemplo: repository.CustomersDAO.GetAll( ICriteria (o detached
criteria).

Eso da mas flexibilidad a los consumidores de los servicios ( en este
caso al diseño del UI ) y simplica el API de los servicios. En caso de
tener todo pre-determinado no existe flexibilidad alguna en el UI.

NOTA: Obviamente teniendo en cuenta que "esta" decision hace que
tengamos que incluir una referencia a Nhibernate.dll
(creo haber leido que se iba a proponer "mover" ICriteria a una DLL
separada para permitir solo linkear el assembly de ICriteria....)


> El UseCase es quien se encarga de manejar la conversation y brindará
> servicios del estilo:
> IsDirty
> Save
> Cancel
> .... what ever.....

Clarisimo.


> Para el prj WEB tendrás que tener cuidado a lo que pasa cuando el
> usuario abandona la sessionWeb mientras que para el prj Win es mas
> facil porque, por lo general, coincide con el close de un form.

OK, o sea para WinForm, cuando el "root form del use case" cierra
basicamente haces un MyUseCase.Dispose().

> En todo el chiste quien mantiene e maneja una session de NH es el UseCase.
Esta claro que no podrias combinar UseCases. (solo como comentario,
estoy de acuerdo que si definimos al use case como meta unit-of-work
no haria falta).

Nota: Voy a incluir un ejemplo de como implementar tu receta de
UseCases en el ejemplo que estoy armando (*).

(*) http://stalamoni.blogspot.com/2007/12/nhibernate-and-winforms-article-1st.html

Saludos,
Sebastian Talamoni

Fabio Maulo

unread,
Jan 3, 2008, 10:35:31 AM1/3/08
to NHibernat...@googlegroups.com
El 3/01/08, tala...@hotmail.com <tala...@hotmail.com> escribió:

> operacion). Me interesaria combinar ambos casos : UseCases como una
> clase derivada de Repository. Voy a investigar un poco el tema...

Ahora me tengo que ir.... despues leo todo el post.

Si vas a investigarlo vas a descubrir que UseCase no debería derivar
de tu Repository.
No sigas quien dice que un BusinessObject representa un UseCase; eso
es verdad solo y exclusivamente para UseCase que representan CRUD.
Un UseCase no tiene "GetAll" y menos tiene "GetById"... "GetAll" que cosa ?
si adentro tiene, por lo general, n BO que se relecionan con otros...
como decir..... un UseCase representa un "comunidad" de
BusinessObjects así que hacerle implementar la interface de un
Repository<T> me parece muy limitado.

Esta noche voy a leer todo tu post.

Bye.
Fabio Maulo

Carlos Peix

unread,
Jan 3, 2008, 1:51:44 PM1/3/08
to NHibernat...@googlegroups.com
Hola Sebastian,

Yo estoy en la misma busqueda que vos (NH+WinForms), asi que a algo util vamos a
llegar seguramente, incluso Gustavo menciona un tema voy a responder mas tarde.

Me gustaria debatir un poco sobre algunas de las cosas que planteas, aunque aun
no tengo respuesta para algunos temas.

En primer lugar quiero dejar clara MI interpretacion de algunos conceptos,
basada casi exclusivamente en DDD:

Repository: un objeto que me permite acceder a una entidad o aggregate. Su
interfaz tiene una semantica de colección, la implemento mediante una interface
definida en el modelo y una implementacion definida en otro assembly, por
ejemplo, usando DAOs NH. Si decidis usar Criterias, te puede quedar una interfaz
pequeña, si no usas, la interfaz es mas amplia.

DAO: Objetos de acceso a datos, dependen de la tecnologia de acceso a datos
elegida. Quedan ocultos en la implementacion del repository.

UseCase Controller: no suelo usarlos, estas clases, tal como dice Fabio, no
deberian heredar del Repositorio, mas bien usan repositorios, incluso varios. Yo
prefiero definir servicios.

Veo en tus comentarios que le das un ciclo de vida a los repositories, eso me
llama la atencion. Yo creo y descarto las instancias de repository cada vez que
los uso. El ciclo de vida la manejo con la sesion de NH y la inyecto en el
repository.

Avanzando mas en este concepto, la sesion de NH y el repository tienen una vida
bastante ortogonal. La sesion vive durante la interaccion puntual con la base
de datos (el UoW), el repository no importa cuando vivam no tiene estado propio,
es una suerte de capa sobre la sesion de NH.

Por supuesto, esto solo vale para las implementaciones de repositories basadas
en NH, los implementaciones en memoria son bien distintas.

Sigamos debatiendo...

Carlos Peix

> -----Original Message-----
> From: NHibernat...@googlegroups.com
> [mailto:NHibernat...@googlegroups.com] On Behalf Of
> tala...@hotmail.com
> Sent: Jueves, 03 de Enero de 2008 12:18 p.m.
> To: NHibernate-Hispano
> Subject: [NHibernate-Hispano] Re: NHibernate & GetCurrentSession
>
>

tala...@hotmail.com

unread,
Jan 3, 2008, 2:29:53 PM1/3/08
to NHibernate-Hispano
> Si vas a investigarlo vas a descubrir que UseCase no debería derivar
> de tu Repository.

Ok, el tema hay un "clash" de terminologia.

Paso a explicar con mas detalles, esta clase es una "mezcla" entre :
a) el ejemplo de Leandro Tutini : http://ltuttini.blogspot.com/2007/08/nhibernate-ejemplo-prctico.html
b) http://www.arcware.net/archive/2006/11/07/NHibernateRepository.aspx
c) http://www.hibernate.org/328.html .

Si leemos el Repository Pattern de Martin Fowler :
http://www.martinfowler.com/eaaCatalog/repository.html la primera
impresion es que estamos re-pifiados y que el nombre no se aplica.
Pero en realidad, si la clase se encarga de encapsular el accesso al
ISession --> en realidad esta mediando y la definicion se aplica.

Debido a que esta clase Repository tiene 2 reponsabilidades basicas :
Encapsula ISession + usa esa misma ISession para todos los DAO .

Ahora veo que Ayende tambien usa en su Rhino Commons (http://
www.ayende.com/Blog/archive/7393.aspx) el termino Repository para
definir lo que en mi ejemplo ( y para http://www.hibernate.org/328.html
) se llama IDAO

Te copio en ingles el "pedazito" del documento donde explico esta
clase.

* This class could have been named "DAO Factory" since it's also
responsible for accessing the DAO instances. (Please give me feedback
about the name).
* Encapsulates ISession, makes sure it disposes any resource , in this
case it's very important since we want to close/dispose the ISession
(IDisposable)
* The DAO's instances actually will "use" the ISession created in the
Repository and will not use a single (static/threaded) session.
o This is the whole point, the ISession is now managed on the
Repository instance.
o This is the Key for multiple sessions support.

Si a alguien se lo ocurre un mejor nombre haganmelo saber.

> No sigas quien dice que un BusinessObject representa un UseCase;

Totalmente de acuerdo. Un UseCase va a utilizar diferentes
BusinessObjects y brindara ciertas propiedades / metodos que
simplifiquen y encapsulen la logica de ese UseCase.

> es verdad solo y exclusivamente para UseCase que representan CRUD.
> Un UseCase no tiene "GetAll" y menos tiene "GetById"... "GetAll" que cosa ?

> si adentro tiene, por lo general, n BO que se relecionan con otros...
Exacto. Puede tambien tener mas de uno en caso que sean objectos "no
relacionados" en el modelo.

Fabio Maulo

unread,
Jan 4, 2008, 7:30:26 AM1/4/08
to NHibernat...@googlegroups.com
Es un nuevo dia... ayer llegue a casa un poco cocinado.... por eso no
hubo commit ;)

El 3/01/08, tala...@hotmail.com <tala...@hotmail.com> escribió:
>

> Duda #1 : Relacion entre UseCase y DAO
> -------------------------------------------
> Algunos UseCases, como EmisionFacturaUseCase, estan claros pero no me
> es facil ver cual el limite entre el UseCase y los DAO.
>

Como me pareció que ya escribió Carlos, si queres comparar UseCase con
algo es mejor que lo compares con el "C" de MVC.

>
> Imaginate que si necesito hacer un Insert de un nuevo cliente dentro
> del NuevaFacturaUseCase se complicarian las cosas. Si cada CRUD tiene
> su UseCase tambien es complicado enmarcar 2 UseCases juntos: ejemplo
> agregar 2 root objects no relacionados entre si (usando misma session
> + misma transaction). Como solucionas este tema?

Normalmente, o por lo menos hasta ahora, si de la emision de un
documento necesito cargar un nuevo cliente yo suelo llamar el UseCase
de CRUDCliente en modalidad Create.
Intento explicar (hice tambien aplicaciones de cero... no solo framework):
Mis clientes que me llamaron a participar de un prj desde su
nacimiento (estos hasta el momento fueron solo prj Windows) tienen
todos un framework de plug-ins. El FW de plug-ins lo hice yo sobre la
experiencia de otro FW que me hice para una aplicación Delphi mia.
Practicamente los UseCase son clasificados por "Context" y "Type". En
el caso de CRUDCustomer el context="Customer" y
Type="Create,Show,Update,Delete" (en realidad sono dos UseCase pero no
la complico). Desde Factura le pido al UseCaseFactory de darme una
instancia del UseCase que se ocupa del Context="Customer" en modalidad
Type="Create"... bueno y lo que sigue (todo eso no es tanto así pero
tengo que describirlo en menos de 200 chars)...

Si lo que el cliente necesita es cargar un su Customer directamente de
adentro de una factura el UseCaseFactura deberá prever eso (fijate que
es muy probable que la cantidad de informaciones del Customer en el
caso de InsideInvoice es probable que sean menores).

> Duda #2: No todo debe/puede estar pre-pensado.
> -----------------------------------------------

> Eso da mas flexibilidad a los consumidores de los servicios ( en este
> caso al diseño del UI ) y simplica el API de los servicios. En caso de
> tener todo pre-determinado no existe flexibilidad alguna en el UI.

Y hace que quien diseña la UI se ocupe de definir temas de negocio.
He esperado tanto tiempo.... ya pasaron 20 años de programación... al
fin quien construye IDE llegó a entender que hay algunos programadores
que están cansado de ser Einstein y Picasso. Parece que con WPF
tendremos clases de programadores que son mas Picasso (y no necesitan
conocer absolutamente nada de negocio) y otros que serán mas Einstein.

>
> NOTA: Obviamente teniendo en cuenta que "esta" decision hace que
> tengamos que incluir una referencia a Nhibernate.dll
> (creo haber leido que se iba a proponer "mover" ICriteria a una DLL
> separada para permitir solo linkear el assembly de ICriteria....)

Escuchaste mal!! Si no queres involucrar la UI con NH (cosa buena y
justa) create tus Criterias. ICriteria de NH está estrictamente
vinculado a otros componentes de NH.
De todos modos eso de no tener la referencia a NH.dll en la UI, aunque
separando ICriteria, seria solo fictizio ya que tendrias una
referencia a NHCriteria.DLL.

>
> OK, o sea para WinForm, cuando el "root form del use case" cierra
> basicamente haces un MyUseCase.Dispose().
>

Si, el UseCase implementa IDisposable ya que deberá hacer Dispose de
session y transaction.

En estas charlas estamos charlando de otras cosas mas que de NH...
pero bueno entiendo que a la hora de usar NH un gran escollo es
tambien el manejo de session.

Bye.
Fabio Maulo

Reply all
Reply to author
Forward
0 new messages