Herramientas de usuario

Herramientas del sitio


unidades:02_hibernate:04_usando_hibernate

Diferencias

Muestra las diferencias entre dos versiones de la página.


unidades:02_hibernate:04_usando_hibernate [2023/04/07 21:26] (actual) – creado - editor externo 127.0.0.1
Línea 1: Línea 1:
 +====== Usando Hibernate ======
 +Hasta ahora hemos visto cómo configurar hibernate usando los ficheros XML de configuración o usando notaciones pero no hemos visto nada de código Java para usarlo realmente. En esta lección veremos finalmente cómo usar Java para persistir una clase.
  
 +La clase que más usaremos en Hibernate es <javadoc h41>org.hibernate.Session</javadoc>. Esta clase contiene métodos para leer, guardar o borrar entidades sobre la base de datos. Pero antes de poder usarla hace falta crear el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc> que mediante el método <javadoc h41>org.hibernate.SessionFactory#openSession()|SessionFactory.openSession()</javadoc> nos dará acceso a <javadoc 41>org.hibernate.Session|Session</javadoc>
 +
 +<code java> 
 +Session session = sessionFactory.openSession();
 +</code>
 +
 +Veamos ahora cómo crear el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc>.
 +
 +===== SesionFactory =====
 +La forma de crear el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc> es mediante un objeto <javadoc h41>org.hibernate.cfg.Configuration</javadoc> que leerá el fichero de configuración de hibernate ''hibernate.cfg.xml'' que se encuentra en el directorio raíz de las clases Java. 
 +
 +<code java 1 | Listado 1.Creación del objeto SessionFactory>
 +import org.hibernate.SessionFactory;
 +import org.hibernate.cfg.Configuration;
 +import org.hibernate.service.ServiceRegistry;
 +import org.hibernate.service.ServiceRegistryBuilder;
 +
 +SessionFactory sessionFactory;
 +
 +Configuration configuration = new Configuration();
 +configuration.configure();
 +ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        
 +sessionFactory = configuration.buildSessionFactory(serviceRegistry);
 +</code>
 +
 +  * En la línea 8 vemos cómo se crea el objeto <javadoc h41>org.hibernate.cfg.Configuration|Configuration</javadoc>
 +  * En la línea 9 mediante el método <javadoc h41>org.hibernate.cfg.Configuration#configure()|configure()</javadoc> se va a leer el fichero de configuración ''hibernate.cfg.xml''
 +  * La línea 10 es nueva en hibernate 4 y contiene la lista de los distintos servicios que usará (( Tiene registrados)) hibernate.Para ello se crea un objeto de la clase <javadoc h41>org.hibernate.service.ServiceRegistry</javadoc>.
 +  * La línea 11 es la que finalmente creará el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc> en función de la configuración y de los servicios.
 +
 +Todo el código anterior deberá realizarse una única vez en la aplicación y deberemos guardar la referencia a <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc> para su posterior uso durante toda la vida de la aplicación.
 +
 +<note tip>
 +Si vemos la [[http://docs.jboss.org/hibernate/orm/4.1/quickstart/en-US/html_single/#hibernate-gsg-tutorial-basic-test|documentación de hibernate 4.1]] se indica que la forma de crear el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc> es la siguiente:
 +
 +<code java 1 | Forma antigua de crear el objeto SessionFactory>
 +Configuration configuration = new Configuration();
 +configuration.configure();
 +sessionFactory = configuration.buildSessionFactory();
 +</code>
 +
 +Sin embargo al usar este código se puede observar que el método <javadoc h41>org.hibernate.cfg.Configuration#buildSessionFactory()|buildSessionFactory()</javadoc> está depreciado.En la documentación del propio método se indica que ahora se use <javadoc h41>org.hibernate.cfg.Configuration#buildSessionFactory(org.hibernate.service.ServiceRegistry)|buildSessionFactory(ServiceRegistry serviceRegistry)</javadoc> es decir que la documentación contiene un error y debemos usar el código del Listado 1.
 +
 +Una discusión sobre el error en la documentación de Hibernate 4 la podéis encontrar en:[[http://stackoverflow.com/questions/8621906/is-buildsessionfactory-deprecated-in-hibernate-4|Is buildSessionFactory() deprecated in hibernate 4?]]
 +
 +</note>
 +
 +Al finalizar la aplicación deberemos llamar al método <javadoc h41>org.hibernate.SessionFactory#close()|close()</javadoc>:
 +<code java>
 +sessionFactory.close();
 +</code>
 +
 +
 +
 +===== Session =====
 +Ahora que ya tenemos el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc> podemos obtener la <javadoc h41>org.hibernate.Session|Session</javadoc> para trabajar con Hibernate. Como ya hemos visto crear la <javadoc h41>org.hibernate.Session|Session</javadoc> es tan sencillo como  llamar al método <javadoc h41>org.hibernate.SessionFactory#openSession()|openSession()</javadoc>:
 +
 +<code java> 
 +Session session = sessionFactory.openSession();
 +</code>
 +
 +Una vez obtenida la sesión trabajaremos con Hibernate persistiendo las clases y una vez finalizado se deberá cerrar la sesión con el método <javadoc h41>org.hibernate.Session#close()|close()</javadoc>:
 +
 +<code java> 
 +session.close(); 
 +</code>
 +===== Transacciones =====
 +Para trabajar con una base de datos usamos las transacciones. En hibernate es tan sencillo como:
 +
 +
 +  * Crear una nueva transacción  llamando al método <javadoc h41>org.hibernate.SharedSessionContract#beginTransaction()|beginTransaction()</javadoc> de la sesión:
 +<code java>session.beginTransaction();</code>
 +\\
 +  * Hacer un commit de la transacción actual llamando al método <javadoc h41>org.hibernate.Transaction#commit()|commit()</javadoc> de la transacción actual de la sesión:
 +<code java>session.getTransaction().commit();</code>
 +\\
 +  * Hacer un rollback de la transacción actual llamando al método <javadoc h41>org.hibernate.Transaction#rollback()|rollback()</javadoc> de la transacción actual de la sesión:
 +<code java>session.getTransaction().rollback();</code>
 +
 +===== CRUD =====
 +Ya hemos llegado al punto en que tenemos todo preparado para poder trabajar con Hibernate en las operaciones fundamentales de una base de datos, las operaciones [[wpes>CRUD]].
 +  * **C**reate: Guardar un nuevo objeto en la base de datos.
 +  * **R**ead:Leer los datos de un objeto de la base de datos.
 +  * **U**pdate:Actualizar los datos de un objeto de la base de datos.
 +  * **D**elete:Borrar los datos de un objeto de la base de datos.
 +
 +Estas 4 operaciones será tan sencillas de usar desde hibernate como llamar a un único método para cada uno de ellos.
 +==== Guardar ====
 +Usaremos el método <javadoc h41>org.hibernate.Session#save(java.lang.Object)|save(Object object)</javadoc> de la sesión pasándole como argumento el objeto a guardar.
 +
 +<code java>
 +Profesor profesor=new Profesor(101, "Juan", "Perez", "García");  //Creamos el objeto
 +
 +Session session = sessionFactory.openSession(); 
 +session.beginTransaction();
 + 
 +session.save(profesor); //<|--- Aqui guardamos el objeto en la base de datos.
 +
 +session.getTransaction().commit(); 
 +session.close(); 
 +</code>
 +
 +Como vemos , guardar una clase Java en la base de datos solo implica usar una única línea. 
 +==== Leer ====
 +El método que debemos usar es <javadoc h41>org.hibernate.Session#get(java.lang.Class, java.io.Serializable)|get(Class,Serializable)</javadoc>, al que le deberemos pasar la clase que queremos leer y su clave primaria.
 +
 +<code java>
 +Profesor profesor=(Profesor)session.get(profesor.class,101);
 +</code>
 +
 +El método <javadoc h41>org.hibernate.Session#get(java.lang.Class, java.io.Serializable)|get(Class,Serializable)</javadoc> permite leer un único objeto de la base de datos a partir de su clave primaria.
 +
 +El uso de este método tiene 2 peculiaridades:
 +  * Uso del cast:Es necesario hacer un cast añadiendo ''(Message)'' en el retorno de la función. Ésto es así ya que el método <javadoc h41>org.hibernate.Session.html#get(java.lang.Class, java.io.Serializable)|get()</javadoc> se usa para cualquier tipo de entidad así que Java desconoce que tipo de datos va a retornar , por lo que debemos decírselo nosotros mediante el cast para "asegurarle" el tipo que retorna.
 +  * El uso de la propiedad ''.class'':Ésta es la forma que se ha definido en en lenguaje Java para pasar un objeto de la clase <javadoc jdk7>java.lang.Class</javadoc>. Véase [[http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.2|Class Literals]].
 +
 +==== Actualizar ====
 +El método a usar es <javadoc h41>org.hibernate.Session#update(java.lang.Object)|update(Object object)</javadoc>, al que le deberemos pasar el objeto a actualizar en la base de datos
 +
 +<code java>
 +session.beginTransaction();
 +
 +session.update(profesor);
 +
 +session.getTransaction().commit();
 +</code>
 +
 +El método <javadoc h41>org.hibernate.Session#update(java.lang.Object)|update(Object object)</javadoc> simplemente actualiza el objeto de la base de datos.
 +
 +==== Borrar ====
 +Ahora pasemos a borrar un objeto desde la base de datos.El método que debemos usar es <javadoc h41>org.hibernate.Session#delete(java.lang.Object)|delete(Object object)</javadoc>, al que le deberemos pasar el objeto a borrar de la base de datos
 +
 +<code java>
 +session.beginTransaction();
 +
 +session.delete(profesor);
 +
 +session.getTransaction().commit();
 +</code>
 +
 +El método <javadoc h41>org.hibernate.Session#delete(java.lang.Object)|delete(Object object)</javadoc> simplemente borra el objeto de la base de datos.
 +
 +==== Guardar y actualizar ====
 +Muchas veces resulta cómodo al programar no tener que estar pendiente de si un objeto va a insertarse o actualizarse. Para ello Hibernate dispone del método <javadoc h41>org.hibernate.Session#saveOrUpdate(java.lang.Object)|saveOrUpdate(Object object)</javadoc> que inserta o actualiza en la base de datos en función de si ya existe o no dicha fila.
 +
 +<code java 1>
 +Profesor profesor=new Profesor(101, "Juan", "Perez", "García");
 +
 +session.beginTransaction();
 + 
 +session.saveOrUpdate(profesor); 
 + 
 +session.getTransaction().commit();
 +
 +</code>
 +
 +En este caso dependiendo de si existe o no la fila en la base de datos con ''Id=101'' se realizará un ''UPDATE'' o un ''INSERT'' contra la base de datos.
 +===== Referencias =====
 +  * [[http://stackoverflow.com/questions/8621906/is-buildsessionfactory-deprecated-in-hibernate-4|Is buildSessionFactory() deprecated in hibernate 4?]]: Discusión sobre el error en la documentación de Hibernate 4.
 +  * [[http://rgordon.co.uk/blog/2012/02/24/hibernate-please-dont-deprecate-yourself/|Hibernate – Please Don’t Deprecate Yourself]]: Post sobre la nueva forma de crear el buildSessionFactory en Hibernate 4.
 +  * [[http://docs.jboss.org/hibernate/orm/4.1/quickstart/en-US/html_single/#hibernate-gsg-tutorial-basic-test|Documentación de hibernate 4.1]]:Documentación errónea sobre crear el objeto <javadoc h41>org.hibernate.SessionFactory|SessionFactory</javadoc>.