Updating a persistent object transparently
En NHibernate, un objeto devuelto medianta búsqueda por identificador, como por ejemplo el método session.Get<T>(int id) o por cualquier otra consulta realizada a través de NHibernate, se asocia al contexto de la session y es lo que llamamos primera cache de NHibernate, first-level cache o session-level cache. En definitiva, una instancia persistente siempre se asocia a una session de NHibernate y tiene un comportamiento transaccional.
using (ISession s = factory.OpenSession()) using (s.BeginTransaction()) { var user = s.CreateQuery("from User") .SetMaxResults(1) .UniqueResult<User>(); s.Get<User>(user.Id); //query no executed. Instance object exists in session s.Transaction.Commit(); }Dichas instancias participan en las transacciones y su estado se mantiene sincronizado al final de la transacción, pero también podría ocurrir antes, ya que se puede dar el caso de que NHibernate tenga la necesidad de sincronizar antes de ejecutar una consulta.
Desde luego, NHibernate no modifica todas las filas que tiene almacenadas en ISession al finalizar cada transacción, esto sería una burrada; sino que sólo lo hace de aquellas que detecta que han cambiado. A este mecanismo se le conoce como "automatic dirty checking". Un objeto que ha sido modificado y aun no se ha sincronizado con la base de datos se le considera "dirty".
using (ISession s = factory.OpenSession()) using (s.BeginTransaction()) { var users = s.CreateQuery("from User") .SetMaxResults(2) .List<User>(); User userNoUpdated = users[0]; User userUpdated = users[1]; userUpdated.Name = "name-updated"; s.Transaction.Commit(); }
Este ejemplo genera las siguientes SQL
Observamos varias cosas:
1. Sólo se modifica el objeto que ha cambiado
En el ejemplo, se obtiene de base de datos dos objetos que almacena en la session, pero sólo se modifica uno por lo que NH lo marca como "dirty" para sincronizarlo al final de la transacción.
2. NHibernate hace un update de todas las columnas
NHibernate es consciente de las columnas que se han modificado y se puede configurar (mediante el uso de dynamic-update="true" en los ficheros de mapeo) para que genere los "update" teniendo en cuenta esas columnas, pero la mejora es tan insignificante que no merece la pena usar, ya que cada vez que tenga que modificar ese objeto va a tener que generar esa sentencia para ese caso particular. Esto es muy costoso comparándolo con la alternativa por defecto, donde se ejecuta el "update" con todas las columnas; en este caso, al inicializar la aplicación, NHibernate genera y cachea la sentencia "update" y, simplemente, se dedica a usarla cada vez que quiera guardar el objeto.
3. La modificación del objeto en base de datos es transparente para el desarrollador
Para modificar el objeto (y con esto me refiero a hacer un "update" en base de datos) no he tenido que llamar a "session.Update();". Para mí, esta funcionalidad es de las más importante que tiene NHibernate. Como he dicho anteriormente, NHibernate es conciente de los objetos que tiene en su session y está atento de los cambios que se producen en ellos. Aquel objeto fuera de su ámbito de session (detached object) no lo monitoriza para observar si cambia o no, y es en este caso especifico, donde se le puede dar uso al "session.Update();". Aquí tenéis un enlace a la referencia de NH. En general, es raro hacer uso del "session.Update()" en patrones "session-per-request", ya que lo normal es recuperar el objeto mediante el "session.Get<T>()" y luego, una vez en la session, trabajar con el.
En definitiva, el hecho de obtener los objetos usando la session de NHiberate nos abstrae de la base de datos y provoca un efecto en el cual podemos trabajar con colecciones de objetos del dominio como si estuvieran en memoria.
¿No os suena está frase? Pues es una definición prácticamente calcada del patrón Repository.
2 comentarios:
Hello there, just turned into aware of your weblog through Google, and found that it's really informative. I am gonna watch out for brussels. I will appreciate if you happen to continue this in future. Many other folks shall be benefited from your writing. Cheers!
Nice locale. Bookmarked:-)
Lo que se encuentra uno buscando páginas de sobre efecto del calentamiento global sobre la bolsa.
Bueno en serio, me alegra leer que publiques cosas (.net of course), y además en inglés.
A ver cuando publicas tu famoso algoritmo para acertar primitivas, que ando canino. Eso si utilizando IoC.
;-)
Un saludo.
Publicar un comentario