martes, 27 de octubre de 2009

Uso insert/update de property en Hibernate

Con estos ejercicios se muestra el uso de insert y update del tag property de hibernate que por default el valor de estas propiedades es true y la anotación @Transient para JPA

Veamos el primer caso usando el xml de mapeo de hibernate

<hibernate-mapping>
<class name="org.dracof.hibernate.Persona" table="PERSONA">
<id name="nombre" column="NOMBRE">
<generator class="assigned"/>
</id>
<property name="apellidoP" column="APELLIDOP"/>
<property name="edad" column="EDAD"/>
</class>
</hibernate-mapping>

Si hacemos operaciones de insert de Persona hibernate genera lo siguiente

Hibernate: insert into PERSONA (APELLIDOP, EDAD, NOMBRE) values (?, ?, ?)

o update

Hibernate: update PERSONA set APELLIDOP=?, EDAD=? where NOMBRE=?

Como vemos se toman en cuenta todos los campos del mapeo, para el caso del insert APELLIDOP, EDAD, NOMBRE y para el update APELLIDOP=?, EDAD=?

Si agregamos la propiedad insert="false" o update="false" en el tag property para edad

<property name="edad" column="EDAD" insert="false"/>

<property name="edad" column="EDAD" update="false"/>

O ambos

<property name="edad" column="EDAD" insert="false" update="false"/>

Vemos que el SQL generado ahora es

Para insert

Hibernate: insert into PERSONA (APELLIDOP, NOMBRE) values (?, ?)

Para update

Hibernate: update PERSONA set APELLIDOP=? where NOMBRE=?

Con esto vemos que hibernate ya no toma la propiedad edad para los insert/update.

Podemos tener el mismo resultado usando las anotaciones JPA con @Transient o la palabra reservada transient de java como sigue

 
@Transient
@Column (name="EDAD")
private Integer edad;

o
 
@Column (name="EDAD")
private transient Integer edad;

Y obtenemos el mismo resultado.

Suerte.

sábado, 24 de octubre de 2009

Uso de dynamic-insert y dynamic-update en Hibernate

Uso de dynamic-insert y dynamic-update en Hibernate

Con este ejemplo salgo de la duda del uso de dynamic-insert y dynamic-update de class, cabe mencionar que ambas son opcionales y por default tienen el valor false.

Estructura de la tabla PERSONA

CREATE TABLE PERSONA (
NOMBRE VARCHAR(10),
APELLIDOP VARCHAR(20),
EDAD INTEGER
);

Todos los campos de la tabla aceptan valores nulos.

Insertamos valores y queda como sigue



Uso de dynamic-insert

Tenemos el objeto Persona para realizar la inserción como sigue

Persona persona = new Persona();
persona.setNombre("Nombre");
persona.setApellidoP("ApellidoP");
//persona.setEdad(15);

NOTA: Observamos que la propiedad EDAD contiene el valor NULL.

Dentro del mapeo de la tabla PERSONA en Persona.hbm.xml, tenemos la propiedad dynamic-insert a false

<class name="org.dracof.hibernate.Persona" table="PERSONA"
dynamic-insert="false">

El query del insert generado por hibernate es el siguiente

Hibernate: insert into PERSONA (APELLIDOP, EDAD, NOMBRE) values (?, ?, ?)

Aquí con dynamic-insert a FALSE se hará el insert con todos los campos aun teniendo un valor NULL, por eso se toma en cuenta la columna EDAD

Ahora probamos con dynamic-insert a TRUE , con esto se hará el insert con todos los campos que tengan un valor DIFERENTE DE NULL

<class name="org.dracof.hibernate.Persona" table="PERSONA"
dynamic-insert="true">

El query generado por Hibernate es

Hibernate: insert into PERSONA (APELLIDOP, NOMBRE) values (?, ?)

La columna EDAD ya no es tomada en cuenta por tener el valor NULL.

Uso de synamic-update

Probamos primero el caso de dynamic-update con FALSE

<class name="org.dracof.hibernate.Persona" table="PERSONA"
dynamic-update="false">

Con esto al obtener un registro y aún cuando no se a modificado algun campo de este objeto hibernate actrualiza los valores de todas las columnas aún cuando no se hayan modificado. Para realizar esta prueba se usa el siguiente fragmento de código

Persona persona = (Persona) session.load(Persona.class, "Dracof");
persona.setApellidoP("Dracof XYZ");
session.update(persona);

Vemos que solo se modifico la propiedad ApellidoP sin embargo tambien setea la columna EDAD aun cuando esta no se modifico, el update generado es

Hibernate: update PERSONA set APELLIDOP=?, EDAD=? where NOMBRE=?

Ahora con dynamic-update con TRUE

<class name="org.dracof.hibernate.Persona" table="PERSONA"
dynamic-update="true">

Corremos el mismo ejemplo pero con dynamic-update con TRUE y vemos que solo setea el valor de la columna APELLIDOP y edad no la toma en cuenta porque no se modifico.

Hibernate: update PERSONA set APELLIDOP=? where NOMBRE=?


Codigo Java

Script SQL

Suerte.

jueves, 22 de octubre de 2009

Ejemplo de Hibernate 3 y Anotaciones JPA Basico

Ejemplo de Hibernate 3 y anotaciones JPA Basico

Esta entrada muestra el uso de las anotaciones de JPA implementadas con Hibernate 3, la estructura del proyecto en eclipse es la siguiente



Al terminar se encuentra el script SQL y codigo en java.

Las librerias importadas son las siguientes

hibernate3.jar
dom4j-1.6.1.jar
log4j-1.2.15.jar
slf4j-api-1.4.2.jar
slf4j-log4j12-1.4.2.jar
commons-collections-3.1.jar
javassist-3.4.GA.jar
antlr-2.7.6.jar
jta-1.1.jar

Las siguientes tres son para el uso de las anotaciones JPA en Hibernate

hibernate-annotations.jar
hibernate-commons-annotations.jar
persistence.jar

Este jar se usa para la conexion con Derby

derbyclient.jar

Iniciamos la construccion de la clase HibernateUtil el cual nos provee un sessionFactory

public class HibernateUtil {
private static final SessionFactory sessionFactory;

static {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}

public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}

Hay que destacar que en este ejemplo no usamos

Configuration().configure().buildSessionFactory();

Si no que usamos AnnotationConfiguration

AnnotationConfiguration().configure().buildSessionFactory();

Usamos las anotaciones JPA en nuestra clase Persona

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table (name="PERSONA")
public class Persona {
@Id
@Column(name="ID_PERSONA")
private Long idPersona;

@Column (name="NOMBRE" , nullable=false)
private String nombre;

@Column (name="APELLIDOP", nullable=false)
private String apellidoPaterno;

@Column (name="EDAD")
private Integer edad;

public Long getIdPersona() {
return idPersona;
}

public void setIdPersona(Long idPersona) {
this.idPersona = idPersona;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public String getApellidoPaterno() {
return apellidoPaterno;
}

public void setApellidoPaterno(String apellidoPaterno) {
this.apellidoPaterno = apellidoPaterno;
}

public Integer getEdad() {
return edad;
}

public void setEdad(Integer edad) {
this.edad = edad;
}
}

Usamos las anotaciones de JPA @Entity, @Table, @Id, @Column, estas son muy intuitivas y faciles de entender.

El archivo hibernate.cfg.xml es el mismo pero con una excepcion

<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
<property name="connection.url">jdbc:derby://localhost:1521/dracof</property>
<property name="connection.user">dracof</property>
<property name="connection.password">dracof</property>

<property name="current_session_context_class">thread</property>
<property name="dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="show_sql">true</property>

<mapping class="org.dracof.hibernate.annotations.Persona"/>
</session-factory>
</hibernate-configuration>

El mapeo ya no lo hacemos con mapping resource y no creamos el archivo Persona.hbm.xml

<mapping resource="org/dracof/hibernate/relacional/Persona.hbm.xml"/>

Si no con

<mapping class="org.dracof.hibernate.annotations.Persona"/>

Y con esto terminamos, hacemos un main con el siguiente codigo

public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.getTransaction();

tx.begin();
Persona persona = (Persona)session.load(Persona.class, new Long(1));
System.out.println("Nombre: " + persona.getNombre());
tx.commit();
}

Obteniendo como resultado

Hibernate: select persona0_.ID_PERSONA as ID1_0_0_, persona0_.APELLIDOP as APELLIDOP0_0_, persona0_.EDAD as EDAD0_0_, persona0_.NOMBRE as NOMBRE0_0_ from PERSONA persona0_ where persona0_.ID_PERSONA=?
Nombre: DRACOF

Codigo SQL

Codigo Java

Suerte.

lunes, 19 de octubre de 2009

Ejercicio Basico Hibernate

Ejercicio Basico Hibernate

Para este ejercicio en Hibernate necesitamos una tabla PERSONA la cual es creada desde Apache Derby, hay una entrada en este blog el cual explica la creación de esta tabla

Creacion Tabla Derby

En la parte final están los scripts y código Java de este ejemplo.

Estructura de la tabla persona

CREATE TABLE PERSONA (
NOMBRE VARCHAR(10),
APELLIDOP VARCHAR(20),
EDAD INTEGER
);

Valores insertados

INSERT INTO PERSONA (NOMBRE, APELLIDOP, EDAD) VALUES ('Dracof','Dracof',28);

INSERT INTO PERSONA (NOMBRE, APELLIDOP, EDAD) VALUES ('Juan','Perez',33);

INSERT INTO PERSONA (NOMBRE, APELLIDOP, EDAD) VALUES ('Maria E.','Andrade',60);

Estructura del proyecto en eclipse



Descargamos el archivo hibernate-distribution-3.3.0.GA-dist.zip desde la siguiente direccion

hibernate-distribution-3.3.0.GA-dist.zip

Lo descomprimimos he importamos las liberarías en nuestro proyecto en eclipse


antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
javassist-3.4.GA.jar
jta-1.1.jar
slf4j-api-1.4.2.jar
hibernate3.jar
slf4j-log4j12-1.4.2.jar
log4j-1.2.15.jar

Para usarlo con Derby importamos ademas las librerias

derbyclient.jar

De inicio creamos una clase para la creación de sessiones hibernate

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable tr) {
tr.printStackTrace();
throw new ExceptionInInitializerError(tr);
}
}

public static SessionFactory getSessionFactory () {
return sessionFactory;
}
}

Creamos un pojo que representa la tabla persona

public class Persona {

private String nombre;
private String apellidoP;
private Integer edad;

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public String getApellidoP() {
return apellidoP;
}

public void setApellidoP(String apellidoP) {
this.apellidoP = apellidoP;
}

public Integer getEdad() {
return edad;
}

public void setEdad(Integer edad) {
this.edad = edad;
}
}

Con su archivo de configuración Persona.hbml.cml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="org.dracof.hibernate.Persona" table="PERSONA">
<id name="nombre" column="NOMBRE">
<generator class="assigned"/>
</id>
<property name="apellidoP" column="APELLIDOP"/>
<property name="edad" column="EDAD"/>
</class>
</hibernate-mapping>


Creamos el archivo de configuración de Hibernate (hibernate.cfg.xml)

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
org.apache.derby.jdbc.ClientDriver</property>
<property name="connection.url">
jdbc:derby://localhost:1530/dracof
</property>

<property name="connection.username">dracof</property>
<property name="connection.password">dracof</property>
<property name="current_session_context_class">thread</property>
<property name="dialect">
org.hibernate.dialect.DerbyDialect
</property>
<property name="show_sql">true</property>

<mapping resource="org/dracof/hibernate/Persona.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Por último creamos una clase Test para probar lo anterios

public static void main(String[] args) {
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Persona persona = (Persona)session.get(Persona.class, "Dracof");
System.out.println( persona.getApellidoP() );
session.close();
}

Este es el resultado de ejecutar el main

Hibernate: select persona0_.NOMBRE as NOMBRE0_0_, persona0_.APELLIDOP as APELLIDOP0_0_, persona0_.EDAD as EDAD0_0_ from PERSONA persona0_
where persona0_.NOMBRE=?

Dracof

Script de este ejercicio script.sql

Codigo de este ejercicio HibernateBasico.zip

Suerte.

martes, 13 de octubre de 2009

Instalacion de Derby en Windows.

Descargamos Derby desde

db-derby-10.5.3.0-bin.zip

Lo descomprimimos en algún lugar de nuestra preferencia, en mi caso C:\Software\
Iniciamos el servidor con el bat startNetworkServer.bat



Iniciamos la herramienta de ejecución de comandos JDBC, con java –jar derbyrun.jar ij dentro del directorio lib, ademas nos conectamos y creamos una base de datos con connect y create en la cadena de conexion



Podemos ver los esquemas existentes con el comando show schemas;



Creamos un esquema con create schema dracof;

ij> create schema dracof;
0 filas insertadas/actualizadas/suprimidas

ejecutamos de nuevo el comando show schemas; nos muestra el esquema dracof que acabamos de crear.



Creamos la tabla Persona con

CREATE TABLE DRACOF.PERSONA (
NOMBRE VARCHAR(10),
APELLIDOP VARCHAR(20),
EDAD INTEGER
);

Con el comando show tables; vemos las tablas existentes.



Insertamos valores en nuestra tabla recién creada

INSERT INTO DRACOF.PERSONA (NOMBRE, APELLIDOP, EDAD) VALUES ('Dracof','Dracof',28);
INSERT INTO DRACOF.PERSONA (NOMBRE, APELLIDOP, EDAD) VALUES ('Juan','Perez',33);
INSERT INTO DRACOF.PERSONA (NOMBRE, APELLIDOP, EDAD) VALUES ('Maria E.','Andrade',60);

Y vemos el resultado lanzando un select sobre la tabla persona.



Ahora creamos una clasesita en Java para conectarnos a la base que hemos creado

public static void main(String[] args) {
try {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}

try {
Connection conn=
DriverManager.getConnection(
"jdbc:derby://localhost:1527/dracof", "dracof", "dracof");

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery( "SELECT * FROM PERSONA" );

while (rs.next()) {
System.out.println( "Nombre: " + rs.getString("NOMBRE") );
System.out.println( "Apellido P: " + rs.getString("APELLIDOP") );
System.out.println( "Edad: " + rs.getString("EDAD") );
System.out.println( "_________________________________________");
}
} catch (SQLException e) {
e.printStackTrace();
}
}

Y obtenemos

Nombre: Dracof
Apellido P: Dracof
Edad: 28
_____________________________________________
Nombre: Juan
Apellido P: Perez
Edad: 33
_____________________________________________
Nombre: Maria E.
Apellido P: Andrade
Edad: 60
_____________________________________________

Para evitar el calificar los objetos nos conectamos de la siguiente manera

connect 'jdbc:derby://localhost:1527/dracof;user=dracof;password=dracof';

Muy simple la instalacion, con esto podemos realizar pruebas de conexión desde Java sin tener un gestor de base de datos pesado en nuestro sistema.

Suerte.

domingo, 11 de octubre de 2009

Instalacion Plugin Apache Derby - Eclipse

Instalacion del Plugin de Apache Derby para el IDE Eclipse Galileo.

Vemos que no existe una opción disponible para Apache Derby, la versión de eclipse para este ejemplo es la 3.5 (Galileo)



Descargamos los plugins desde las siguientes direcciones

derby_core_plugin_10.5.3.zip

derby_ui_doc_plugin_1.1.2.zip

Descomprimimos y copiamos los directorios

org.apache.derby.core_10.5.3
org.apache.derby.plugin.doc_1.1.2
org.apache.derby.ui_1.1.2

a la carpeta ECLIPSE_HOME\plugins, reiniciamos eclipse y vemos que tenemos ya la opción en menú de Apache Derby



Damos clic derecho en el proyecto, seleccionamos Apache Derby y oprimimos en “Add Apache Derby nature”, con esto nos muestra un mensaje en la parte inferior de eclipse que dice



Con esto el menú cambia mostrando



Seleccionamos la opción “Start Derby Network Server”
Si vemos un mensaje dentro de la consola de eclipse

Se ha instalado el administrador de seguridad utilizando la directiva de seguridad de servidores básica.
Apache Derby Network Server - 10.5.3.0 - (802917) se ha iniciado y est?° listo para aceptar conexiones en el puerto 1527

Ya esta listo para aceptar conexiones en el puerto 1527.

Si recibimos un mensaje de error diciendo que el puerto ya está en uso, podemos cambiar el puerto por default (1527) por el de nuestra preferencia, hacemos clic derecho del proyecto, seleccionamos Propiedades, Apache Derby y vemos una ventana en la cual podemos cambiar el puerto en “Network Server Port”



Suerte.