Mostrando entradas con la etiqueta jpa. Mostrar todas las entradas
Mostrando entradas con la etiqueta jpa. Mostrar todas las entradas

Integracion de Liquibase con Spring y JPA

¿Qué es Liquibase?

Liquibase, es una libreria opensource para gestionar los cambios en base de datos. En la etapa de desarrollo de un sistema casi como norma debe versionarse el código fuente, pero no había un mecanismo para llevar un control de los cambios en la estructura de la base de datos y de esta necesidad nace liquibase.

En un equipo de desarrollo es habitual que cada miembro realice procedimientos almacenados, vistas o cambios en las estructuras de las tablas en función de las funciones que este desarrollando y al momento de integrar todo se vuelve un quilombo. Con liquibase los cambios se realizan a través de un archivo de cambios el cual se sincroniza con los demás miembros del equipo, de esta forma los cambios no se hacen directamente a la base de datos sino desde la aplicación al momento de su ejecución.

Desarrollare un pequeño ejemplo de como implementar esta libreria con Spring y JPA, del lado de la base de datos utilizare PostgreSQL. Supondremos que ya tenemos creado nuestro acceso a datos y procedemos a configurar el contexto de spring.


Ahora se debe configurar el archivo donde se declaran los cambios en la base de datos.

Cuando ejecutemos la aplicación liquibase intentara primeramente hacer efectivos los cambios configurados en db-changelog.xml

En el caso de JPA, es de tener en cuenta que siempre hay que actualizar manualmente los Entity class, ya que no es parte de las funciones de liquibase.

Adjunto código fuente para efectos de estudio.

Comentarios (1)opiniones, ¿cual es la tuya?

Spring 3.0 y JSF 2.0

Hace poco me había planteado la necesidad de utilizar una capa de servicios potente como EJB 3.0 pero sin utilizar un servidor de aplicaciones sino un simple tomcat, ya que este no es un contenedor de EJB. Así que me decidi por la combinación Spring 3.0 y JSF 2.0, la reseta de implementación JPA 2.0 para Spring utilizare Hibernate. Aca desarrollare un ejemplo de como utilizar las dos tecnologías antes mencionadas. Antes que nada es necesario configurar un datasource el cual accederemos desde spring vía jndi, para el ejemplo accederemos a la base de datos derby que esta embebida con netbeans. En el archivo contex.xml del tomcat creamos el datasource.
 
Ahora procedemos con la capa de acceso a datos generando los entities de las tablas "customer" y "discount_code". Modificamos el archivo persistence.xml que debera quedar de la siguiente manera:
Creare la interfaz con la con la cual las transacciones de spring funcionaran
 
Luego creo la implementación
 
 El siguiente paso es configurar el archivo de spring applicationContex.xml en la ubicación WEB-INF
Ahora vamos con la parte de la vista. Se debe configurar el proyecto web para que JSF pueda interactuar con Spring. Se agregan las siguientes líneas en el archivo web.xml:
 
 Luego se debe configurar el archivo faces-config.xml para que spring pueda realizar inyección de dependencias a través de el lenguaje de extextareasiones de JSF, se debe crear sino existe.
Luego creo el managed bean
 
Por ultimo desplegamos la java.util.Lista "customers" del managed bean en nuestra página xhtml
El resultado sera el siguiente
Adjunto el código fuente para efectos de estudio.

Comentarios (1)opiniones, ¿cual es la tuya?

Spring 3.0 e Hibernate JPA 2.0

Hace unos días me decici a integrar Spring con la implementacion JPA 2.0 de Hibernate. En esta ocasión la versión de spring que usare es la 3.0 de Hibernate 3.6.7 y la base de datos de ejemplo (derby - sample) que se encuentra embebida en Netbeans.

Los jars necesarios para utilizar la implementación JPA de Hibernate, en donde {hibernate-path} es la ruta donde esta descomprimido la distribución final de Hibernate 3.6.7:

{hibernate-path}\lib\jpa\hibernate-jpa-2.0-api-1.0.1.Final.jar
{hibernate-path}\lib\required\antlr-2.7.6.jar
{hibernate-path}\lib\required\commons-collections-3.1.jar
{hibernate-path}\lib\required\dom4j-1.6.1.jar
{hibernate-path}\lib\required\javassist-3.12.0.GA.jar
{hibernate-path}\lib\required\jta-1.1.jar
{hibernate-path}\lib\required\slf4j-api-1.6.1.jar
{hibernate-path}\hibernate3.jar

Como nota aclaratoria es tambien necesario agregar el jar aopalliance.jar para poder utilizar la anotación @Transactional, en este ejemplo no realizaremos un CRUD por esa razón no se incluye.


Y la versión 3.0 de Spring que viene con Netbeans.

Las tablas que utilizare son "Product", "Manufacturer" y "Product_Code", al mapear las tablas con el asistente de Netbeans obtengo sus clases

La unidad de persistencia debera quedar de la siguiente forma:




  
    org.hibernate.ejb.HibernatePersistence
    org.dani.ejemplo.jpa.dao.ProductCode
    org.dani.ejemplo.jpa.dao.Product
    org.dani.ejemplo.jpa.dao.Manufacturer
    
  


Creo el acceso a datos para las tablas.

package org.dani.ejemplo.jpa.dao;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import java.util.*;
/**
 *
 * @author dherrera
 */
public class DerbySampleDAO extends JpaDaoSupport{

    public List getAllProducts() {
        return getJpaTemplate().find("Select p From Product p");
    }
}


Luego procedo a configurar el archivo de configuración de spring



    


    
     
    
        
            
            
        
    
    
        
    


    
    
    
    


    
    

    




Y la forma de uso sera de la siguiente forma:

package org.dani.ejemplo.jpa;

import java.util.List;
import org.dani.ejemplo.jpa.dao.DerbySampleDAO;
import org.dani.ejemplo.jpa.dao.Product;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @author dherrera
 */
public class Init {

    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("/org/dani/ejemplo/jpa/applicationContext.xml");
        DerbySampleDAO dao=(DerbySampleDAO) ctx.getBean("dao");
        List list=dao.getAllProducts();
        for(Product product:list)
            System.out.println(product.getDescription());
    }
}

Adjunto el código fuente de ejemplo aca.

Comentarios (0)

EJB: Usando consultas SQL nativas

Cuando hablamos de EJB (Enterprise JavaBeans) indudablemente tenemos que hablar sobre JPA.

Siempre me ha parecido algo rigido el hecho de tener que usar consultas JPQL para generar mis Entity Class, aunque estar este tipo de consultar resulta beneficioso a la hora de cambiar de base de datos completamente ya que para la base de datos es transparente el JPQL. y aporta mucho a a la portabilidad del código con respecto a la base de datos.

Pero en ocasiones necesitamos hacer uso de caracteristicas propias de la base datos para crear consultas mas complejas y nos vemos limitados por el JPQL entonces vemos la necesidad de utilizar consultas SQL nativas y a la vez son mucho más rapidas que las JPQL.

¿Como se utilizan?

Se podría decir que la sintaxis es la siguiente:

Query createNativeQuery(String sql, Class entityClass)

Donde:

Parametro uno: String sql
Es la consulta SQL nativa en el cual deben de ir los campos que conformaran nuestra Entity Class.

Parametro dos: Class entityClass
Es la Entity Class resultante de la consulta nativa SQL.

Ahora como siempre recalco, es tipico de este blog desarrollar un pequeño ejemplito de uso.

Asumiendo, ya tenemos generadas nuestra Entity Class llamada Persona procedremos a generar una lista de "personas".

EntityManagerFactory emf=Persistence.createEntityManagerFactory("nombreUnidadPersistencia");

EntityManager em=em.createEntityManager();
String consulta="select * from persona";
Query q=em.createNativeQuery(consulta,com.paquete.modelo.Persona.class);
Persona[] personas=(Persona[])q.getResultList().toArray(new Persona[0]);

for(Persona p:personas)
System.out.println(p.getPropiedad());

A veces no queremos tener un array de Entity Class sino que queremos obtener un valor escalar proveniente de una función sum, avg, max, etc...

EntityManagerFactory emf=Persistence.createEntityManagerFactory("nombreUnidadPersistencia");
EntityManager em=em.createEntityManager();
String consulta="select sum(campo) from tabla";
Query q=em.createNativeQuery(consulta);
double total=((BigDecimal)((List)q.getSingleResult()).get(0)).doubleValue();

De esta forma podemos trabajar con consultas SQL nativas y poder hacer uso de las capacidades de nuestra base de datos.

Comentarios (5)

ICEfaces: Incluir dropdown List (combos) en tablas

El día de ayer el compañero Hugo me manifestaba su inquietud de como incluir un combo (SelectOneMenu) dentro de una tabla con ICEfaces a su vez que este combo tuviera seleccionado el elemento correspondiente a cada registro de tabla para posteriormente poder modificarlo.

Pues bien me parecio buena idea desarrollar la solución al problema planteado anteriormente, pues para el ejemplo que expondre a continuación se utilizaran las siguiente herramientas:
Antes de iniciar cabe aclara que siempre es fundamental utilizar Convertidores personalizados a la hora de utilizar SelectOneMenu y JavaBeans pues resuelven la vida muchisimo.

Paso Uno

Crear un proyecto de Persistencia de datos para la base de datos Sample en Derby que viene con Netbeans, pero lo principal es a clase "Dao" que es donde obtengo todos mis Entity Class:


Paso Dos

Crear nuestro proyecto Web utilizando los frameworks ICEfaces y Facelets, y crear nuestro Convertirdor para el objeto Manufacturer y posteriormente registrarlo en faces-config.xml

Registro del convertidor en faces-config.xml

Paso Tres

Ahora creamos nuestro Managed Bean que le llamaremos TemplateClient al igual que la página template-client.xhtml, nada mas para efectos de saber que corresponde a ese xhtml y será de tipo request.


Paso Cuatro

Nada mas debemos diseñar nuestro página xhtml que es la template-client.xhtml


Ahora solo debemos ejecutar la aplicación que se verá de la siguiente manera

Adjunto el proyecto para efectos de estudio.

Comentarios (1)opiniones, ¿cual es la tuya?

Crosstab con ICEfaces

Una de las cosas que se hace bastante uso en las aplicaciones de gestión es la elaboración de tablas para presentar datos, y entre muchos casos que se me han presentado a veces es necesario generar tablas en la cual tanto las filas como las columnas van creciendo a esta situación se le denomina Crosstab en inglés.

Últimamente en mi trabajo los recientes proyectos los he estado realizando mediante ICEfaces que me ha reducido considerablemente el tiempo desarrollo gracias a su implementación de Ajax y por el lado de los usuarios que obtienen aplicaciones mucho mas parecidas como si fueran de escritorio como están acostumbrados.

Antes que comenzar a desarrollar el proyecto necesitamos tener una base de datos, para este caso utilizare derby que ya esta embebido con Netbeans, así no tengo que obligar a mi lectores instalar ya sea MySQL, PostgreSQL u Oracle.

Mi base de datos le llame crosstab y la estructura de las tablas es la siguiente:

create table producto (
id int not null primary key generated always as identity,
descripcion varchar(20) not null
)

create table periodo (
id int not null primary key generated always as identity,
inicio date not null,
fin date not null
)

create table precio (
id int not null primary key generated always as identity,
valor double not null,
fk_producto int not null,
fk_periodo int not null,
constraint precio_producto foreign key(fk_producto) references producto(id),
constraint precio_periodo foreign key(fk_periodo) references periodo(id)
)


Nota: Es necesario agregarle registros, la aplicación que se desarrollara no tendrá ninguna validación en cuanto si en la tabla se encuentran datos nulos en la tabla Precio. Adjuntare el código fuente del proyecto con el respectivo script SQL de la estructura de la base de datos que puede ser descargado al final de este post.

Pues bien ahora es el momento de echarle mano al desarrollo de la aplicación, en mi caso me gusta crear mis Entity Class como un proyecto de librería de Java para tener separada la lógica del negocio con la interfaz web mi proyecto se llamara JavaCrosstab.

La forma para generar Entity Class con JPA ya fue tratado a anteriormente, así que en el proyecto se agregara nada mas una Clase llamada Control.

Nota: Hay que recordar que habrá que agregar posteriormente las librerías TopLink y derbyClient al Tomcat, por que el proyecto web lo hare con este servidor.

Ahora el ejemplo que desarrollare estará hecho con Facelets, no entrare en detalles como crear un proyecto Facelets ya que esto ya lo he hecho, pues nada mas me centrare en la forma de crear la tabla mediante ICEfaces y JPA.

Pues procedemos a crear un proyecto Web con Netbeans con los frameworks ICEfaces y Facelets llamado WebCrosstab, deberemos agregar el proyecto donde se encuentra nuestros Entity Class creado anteriormente llamado JavaCrosstab luego crear un Managed Bean llamado ConversorDolares, a este Bean deberá tener la siguiente estructura:

Este Managed Bean hereda de la clase "AbstractPageBean" para poder acceder a los métodos "getValue" y obtener el valor de la columna y fila actual cuando se este generando la tabla en la pagina template-client.xhtml.

Ahora editaremos la página template-client.xhtml con el siguiente contenido:


Hecho esto nada mas bastara iniciar la base de datos crosstab de derby en Netbeans, realizar deploy al proyecto WebCrosstab y acceder a la ruta http://localhost:8084/WebCrosstab.


Adjunto el código fuente del proyecto WebCrosstab y la estructura de la base de datos.

Comentarios (6)

Obteniendo una Conexion a partir de un EntityManager

Hace unos dias cuando estaba realizando unos reportes con la herramienta iReport, me tope con la necesidad que para poder invocar los reportes elaborados era necesario enviar una instancia de un objeto Connection para el metodo que genera el reporte.

Crear una conexion es sencillo pero yo no estaba manejando mi conexion de la manera tradicional pues estaba usando JPA que es la API de persistencia de datos de Java y esta es la que maneja las conexiones y la configuracion de la cadena de conexion se guardda en la unidad de persistencia que es nada mas y nada menos que un XML.

En un principio pense en acceder al XML directamente, pero como sabia que la conexion se maneja a traves del objeto EntityManager decidi averiguar como se hacia y pues la forma fue la siguiente asi de simple:

public Connection getConnection() {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("NombreUnidadPersistencia");
EntityManager em=emf.createEntityManager();
return ((oracle.toplink.essentials.ejb.cmp3.EntityManager)em)
.getServerSession()
.getDefaultConnectionPool()
.acquireConnection()
.getConnection();
}


Espero que esto le sirva cuando se tenga la necesidad de obtener una instancia de la conexion que esta utilizando a travez de un EntityManager.

Comentarios (3)

Introduciendo al uso de persistencia de datos JPA

Como parte de mi promesa de volver a bloguear activamente, ahora voy a escribir sobre el uso de la API de persistencia de datos de Java comunmente llamado JPA.


Pero antes de empezar este post aun recuerdo cuando Rodrigo queria implementar esta historia en nuestro proyecto de Sistemas de informacion gerencial, definitivamente si a mi no me hubiera agarrado el berrinche hubiesemos avanzado bastante en poco tiempo, ya que perdi bastante tiempo queriendo escribir mis diske reglas del negocio, por eso en ese caso se aplico bien lo que dicen la gente adulta "uno de cipote es tonto".

Este post se centrara en utilizar JPA utilizando el IDE Netbeans 6.1, ya que es el que tengo mas tiempo utilizandolo, y en mi caso la base de datos de mi preferencia es PostgreSQL.

La base de datos que cree la llame simplemente "tienda" y su estructura esta compuesta por dos tablas:

CREATE TABLE tienda
(
id serial NOT NULL,
descripcion character varying(20),
CONSTRAINT pk_tienda PRIMARY KEY (id)
)

CREATE TABLE empleado
(
nick character varying(15) NOT NULL,
nombre character varying(30),
fk_tienda integer,
CONSTRAINT pk_empleado PRIMARY KEY (nick),
CONSTRAINT tienda_empleado FOREIGN KEY (fk_tienda)
REFERENCES tienda (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)

Luego de esto nos dirigimos a nuestro Netbeans y creamos un proyecto "Java Application", creamos el nombre que nos plazca en mi caso le coloque JPAejemplo, incluso deje que el Netbeans me creara una clase con el metodo main que es alli donde mostrare su uso.


Luego de esto nos vamos a la pestana de "servicios" y creamos una nueva conexion a una base de datos, lo bueno de usar Netbeans es que ya trae el driver para PostgreSQL o si se desea tambien MySQL, si se esta usando algun otro como SQL Server, Oracle, SyBase, etc., es necesario agregarlo.


Para crear la nueva conexion hacemos clic derecho sobre el nodo que dice "Databases" en la pestana de servicios, y elegir la opcion "New Connection" del menu emergente. Ingresamos los datos necesarios para pegarnos a nuestra base de datos y damos aceptar.


Ya teniendo nuestra conexion abierta procedemos a crear nuestros objetos de reglas del negocio persistentes.

Para ello damos clic derecho sobre el proyecto, elegir nuevo y dar clic en la opcion "Entity Classes from Database", aparecera un asistence para la creacion de nuestros objetos persistentes.

El primer paso es elegir la conexion que creamos, para luego escoger las tablas que estaran involucradas.

Luego dar siguiente el asistente nos preguntara el nombre que le daremos a nuestras clases asi como tambien el paquete donde las encapsularemos.


Notese hay una alerta la cual indica que no hemos creado una unidad de persistencia debemos crearla para poder proseguir, asi que hacemos clic en el boton "Create Persistence Unit".


En la ventana de dialogo por lo general no se toca simplemente lo dejamos como esta siempre recordando el nombre de la unidad de persistencia que en este caso se llamara "JPAejemploPU", que luego la utilizaremos pero eso sera solamente una vez.

Ya generada la unidad de persistencia precionaremos el boton finalizar. Si seguimos los pasos tal cual como lo he indicado debemos tener dos clases creadas una llamada "Empleado" y la otra "Tienda".

Ahora para poder continuar debemos tener claro el tipo de dato que son las llaves primarias de las dos tablas que creamos en el caso de la tabla Tienda su llave primaria es de tipo "Serial" es equivalente a la opcion autoincrement de MySQL o IDENTITY de SQL Server.

Teniendo claro eso definimos la forma en la clase Tienda de como se generara el codigo primario cuando se indique que queremos realizar por decirlo asi un insert.

En la seccion del campo Id de la clase Tienda debemos agregar lo siguiente:

GeneratedValue(strategy=GenerationType.IDENTITY)

Esto se coloca despues de la anotacion "Column" del campo Id, que debe quedar asi:

@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;


No hay que olvidar agregar los respectivos import.

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;


Con esto que se le agrego a la clase indicamos la forma de generar el valor para el campo Id en cada insert.

Ese tipo de generacion aplica para base de datos MySQL, SQL Server, Sybase, PostgreSQL (cuando trata de campos de tipo serial).

Pero cuando usamos secuencias se debe utilizar otro tipo de generacion de valores, como es el caso para Oracle, que en otro post lo explicare con mas detalle.

Pero bien no basta con solo agregar eso a la clase, tambien es necesario crear nuestras "Consultas nombradas", por esta caracteristica es que me gusto bastante esto del JPA, ya que es bastante, bastante flexible.

Creamos una simple para mostrar todos los empleados, ahora procedemos a editar la clase Empleado y en la anotacion "NamedQueries" agregamos la nuestra tan simple como esto:

@NamedQuery(name="Empleado.verTodos", query="SELECT e FROM Empleado e")

Que al final debe quedar asi:

@NamedQueries({
@NamedQuery(name="Empleado.verTodos", query="SELECT e FROM Empleado e"),
@NamedQuery(name = "Tienda.findById", query = "SELECT t FROM Tienda t WHERE t.id = :id"), @NamedQuery(name = "Tienda.findByDescripcion", query = "SELECT t FROM Tienda t WHERE t.descripcion = :descripcion")})

Ya hecho todo esto, pasamos a la parte mas interesante, que es utilizar nuestras clases ya configuradas, para ello creamos dos clases mas para la manipulacion de las ya antes mencionadas.

Una la llamaremos ControlEmpleado.java y la otra ControlTienda.java

El objetivo de estas sera mostrar consultar, agregar, eliminar o modificar un objeto en especifico.

Pero para no hacer mas largo este post de lo que ya esta por que me estoy cagando del sueno solo mostrare como mostrar los resultados de una consulta, y realizar un insert.

Pues bien para realizar un insert nos vamos a la clase ControlTienda y agregamos el siguiente metodo:

public void insertPrueba() {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("JPAejemploPU");
EntityManager em=emf.createEntityManager();

Tienda nueva = new Tienda();
nueva.setDescripcion("Otra tienda");

em.getTransaction().begin();
em.persist(nueva);
em.getTransaction().commit();
}


Eso es todo, lo mas correcto hubiera sido que el metodo recibiera una instancia de tienda y luego por medio de JPA se realizara el insert, pero el punto era mostrar como se hace.

Ahora como mostramos los registros? pues es tambien muy sencillo, y eso haciendo uso de nuestra consulta nombrada.

Creamos otro metodo en la clase ControlEmpleado, que devuelva un arreglo de Empleados.

public Empleado[] getEmpleados() {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("JPAejemploPU");
EntityManager em=emf.createEntityManager();

Query q = em.createNamedQuery("Empleado.verTodos");

return (Empleado[]) q.getResultList.toArray(new Empleado[0]);
}

Ya con esto desde el metodo main hacemos un recorrido por los registros que nos devuelva nuestro metodo.

Empleado[] empleados = new ControlEmpleado().getEmpleados();

for (int i= 0 ;i
System.out.println(empleados[i].getNombre()+ " trabajo en "+empleados[i].getTienda().getDescripcion());



Y eso es todo, espero poder aportar mas con lo que he quedado pendiente en este post, saludos marachitos.

Comentarios (4)