Professional Documents
Culture Documents
Diciembre 2008
Incompatibilidades entre OO y MR
El problema aparece cuando intentamos traducir objetos a tablas relacionales.
Granularidad Subtipos Identidad Asociaciones direccionales
Problema de la Granularidad
Los objetos en OO son multidimensionales En SQL los tipos y las relaciones entre tablas son planas y hay un escaso soporte para tipos definidos por el usuario. Esto fuerza a los desarrolladores a usar estructuras menos flexibles en el modelo de objetos.
Problema de la Identidad
Comprobar si dos objetos son iguales Java define dos notaciones: Identidad de objetos [==] Equivalencia de valor [.equals()] Para SQL dos registros son el mismo si contienen la misma clave primaria. Dos o ms objetos pueden representar la misma fila (registro) en la BBDD.
Diferencias en la navegacin
Los objetos son accedidos de forma totalmente diferente en Java y en SQL obj.getDetails().getFirstField() En SQL estos detalles se obtendrian a travs de uno o varios join.
10
11
13
Tipos de ORM
1. Puramente relacional
Generan el modelo de objetos equivalente al modelo relacional Desaprovechan las ventajas OO, y son dificilmente portables. Utilizan SQL/JDBC para crear soluciones de mapeo a medida Esta solucin continua siendo muy popular Son capaces de generar el cdigo relacional en tiempo de ejecucin para los casos mas simples Soportan modelado de caracterscas sofisticadas como: composicion, herencia, polimorfismo & persistencia.
16
Se calcula que un motor de persistencia puede reducir el cdigo de una aplicacin en un 40%, hacindola menos costosa de desarrollar. Adems, el cdigo que se obtiene programando de esta manera es ms limpio y sencillo y, por lo tanto, ms fcil de mantener y ms robusto.
La estructura de Bean es muy importante para hibernate ya que la capa de persistencia autoinstanciar las clases y no podra hacerlo si no proveemos un constructor vacio. Hibernate reconoce los mtodos standart SET, GET, IS..
El archivo de mapeo
Hibernate necesita saber cmo cargar y almacenar objetos de la clase persistente. Aqu es donde entra en juego el archivo de mapeo. Un archivo de mapeo es un archivo XML que cumple con el DTD de los archivos de mapeo de hibernate. Este DTD es complicado por lo que lo iremos viendo poco a poco.
El archivo de mapeo
Para nuestro ejemplo el fichero de mapeo podra ser:
La etiqueta CLASS es la mas importante porque define la tabla de la bd donde se persisten los objetos La etiqueta ID define el mapeo del identificador nico a la clave primaria de la tabla. La etiqueta GENERATOR indica una estrategia de generacin automtica. En este caso de tipo nativo.
El archivo de mapeo
Para nuestro ejemplo el fichero de mapeo podra ser:
La etiqueta PROPERTY declara una propiedad persistente. POR DEFECTO TODAS LAS PROPIEDADES DE LA CLASE SON NO PERSISTENTES. El atributo name declara el nombre de la propiedad java. Hibernate usar ese nombre para acceder a Los mtodos GET/SET correspondientes.
El archivo de mapeo
Para nuestro ejemplo el fichero de mapeo podra ser:
Por qu el mapeo de la propiedad date incluye el atributo column pero el de title no? Por qu el mapeo de title no incluye type? Hibernate no puede decidir automaticamente si el tipo de la columna que proviene de un atributo Java.util.Date ser Date Time Timestamp.
Configurar el entorno
Para la configuracin de Hibernate podemos usar un simple archivo hibernate.properties, un archivo hibernate.cfg.xml algo ms complicado, o incluso una configuracin totalmente en tiempo de ejecucin. Probablemente la solucin mas versatil sea el fichero xml. Para nuestro ejemplo el fichero cfg.xml podra ser:
Configurar el entorno
Lo primero que hay que darse cuenta es que este fichero tiene su propia DTD que tenemos que seguir. Configuramos la SessionFactory una fabrica global responsable de una base de datos en particular.
Configurar el entorno
La propiedad hibernate.dialect especifica la variante de SQL que hibernate generar para hablar con la BD. Al contrario que JDBC hibernate nos permite adaptarnos al dialecto hablado por la BD.
Configurar el entorno
La propiedad hibernate.current_session_context_class es muy importante porque define el comportamiento de las sesiones. En este caso la unidad de trabajo de hibernate queda ligada al thread de java que se este ejecutando en el momento de crearla. Veremos esto mas adelante.
Configurar el entorno
Por ltimo declaramos los ficheros que contendrn los mapeos de los objetos en la BD.
HibernateUtil.java
Llegados a este punto Hibernate es capaz de conectar con nuestra BBDD, manejar la conexin independientemente de que esta se obtenga a travs de JDBC o de otros mecanismos como JNDI, y escribir-leer objetos en ella. Lo nico que necesitamos es una clase que nos permita comunicarnos con hibernate para solicitarle operaciones. Esta clase es HibernateUtil.java
Lo que nos va a importar de hibernateUtil.java es que nos provee de una clase singleton capaz de crear un objeto SessionFactory de forma unica, mantenerlo de forma global y devolverlo de forma facil.
HibernateUtil.java
Una implementacin bsica de HibernateUtil suele estar incluida en todos los entornos de desarrollo y en nuestro caso podra ser:
Lo primero que hacemos es obtener la unidad de trabajo actual (CurrentSession) a travs de HibernateUtil. Hemos asignado cada unidad de trabajo a un thread. Una sesin comienza cuando se la necesita por primera vez, entonces queda ligada al thread actual. Si volvemos a llamar a getCurrentSession obtenemos la misma unidad de trabajo. Una vez que la transaccin termina Hibernate desliga la sesin y la cierra automaticamente.
Una transaccin en la BD siempre se inicia invocando al mtodo beginTransaction() del objeto sesin y terminar bien en una confirmacin, bien en una orden deshacer.
Lo que hicimos aqu, es usar el lenguaje de consultas de Hibernate (HQL, por sus siglas en ingls) para cargar todos los objetos Event que existen en la base de datos. Hibernate generar el cdigo SQL que haga falta, lo enviar la base de datos, y poblar los objetos Event con los datos que sean devueltos. Se pueden crear consultas SQL mucho ms complejas con HQL, por supuesto. Pero es importante que esto no es SQL sino HSQL, que veremos en detalle mas adelante.
Ejercicio inicial
Crear un proyecto base en NetBeans integrando Hibernate.
hacer en clase
Otro Ejemplo
public class Message { private Long id; private String text; private Message nextMessage; private Message() {} public Message(String text) { this.text = text; } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public Message getNextMessage() { return nextMessage; } public void setNextMessage(Message nextMessage) { this.nextMessage = nextMessage; } }
36
Otro Ejemplo
La clase mensaje puede ser usada como cualquier otra clase
Message message = new Message("Hello World"); System.out.println( message.getText() );
37
Otro Ejemplo
El Cdigo de traduce a
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (1, 'Hello World', null)
38
Otro Ejemplo
Que se traducira a:
select m.MESSAGE_ID, m.MESSAGE_TEXT,m.NEXT_MESSAGE_ID from MESSAGES m order by m.MESSAGE_TEXT asc
40
Otro Ejemplo
Podemos Actualizar un mensaje haciendo:
Session session = getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); // 1 is the generated id of the first message Message message = (Message) session.load( Message.class, new Long(1) ); message.setText("Greetings Earthling"); Message nextMessage = new Message("Take me to your leader (please)"); message.setNextMessage( nextMessage ); tx.commit(); session.close();
41