11.13.2013

WebService Java y JPA

Para todos no es una novedad que netbeans nos provea de herramientas para automatizacion de tareas tan tediosas como el mapedo de datos desde una Base de Datos, para eso se creo JPA con las muy conocidas EntityClasses, las cuales permiten tener un objeto de JAVA que representa una tabla, es decir:


create table sampe (
   idTabla int not null,
   someText varhcar(50),
   someDate timestamp
);

lo que en JAVA representaria, esto aun no es JPA:

public class Sample{

private int idTabla;
private String someText;
private Date someDate;

}

Para que la clase sea totalmente compatible con JPA se utiliza la notacion JAXB, pero bueno para eso no es la entrada si quieren leer un poco mas de JPA pueden echarle una revisada a este documento de oracle:
http://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.html


Bueno, lo cierto es que para trabajar con WebServices es necesario tambien tener una notacion para que el contenedor de aplicaciones o servidor o como lo quieran llamar pueda interpretar lo que tiene este, algo como:


@WebService(serviceName = "GestorSample")
public class GestorSample {

/***El metodo del webservices***/
@WebMethod(operationName = "impSample")
    public String impLicencia(@WebParam(name = "sampleOBJ") Sample sample) throws Exception {
        System.out.println(sample);
}
}
Listo, ese seria el mejor ejemplo con el WebService, pero si nos damos cuenta esa seria la clase que se crearia apartir de JPA, la cual ya tendra una notacion JABX por lo cual al momento de generar el descriptor XML del WebServices generara un error y lo mas probable es, que el objeto llamando sample no llegue, llegara un null lo cual pondra en tela de juicio nuestra creacion del webServices. Dado esto no lei mucho, pero supuse lo siguiente si el objeto que esta como parametro del webservices tiene ya una notacion JABX sera que tiene problema con la notacion de JABX del webservices y si que realmente tienen un conflicto puesto que las notaciones llegan a confundir la generacion del WebServices y genera inconsistencias imperceptibles, pero bueno eso me paso y lo unico para hacer es crear una clase con los atributos iguales a los del JPA y para que sea de reconocimiento ponerle algo como ClassNoJPA para no confundirse con las clases reales de persistencia.


Listo, los dejo con eso que les rinda!!

11.12.2013

Postgres Triggers

Bueno, he estado probando como es que postgres maneja los famosos triggers alias disparadores para los del idioma español jejejeje, entonces esto empieza asi:


 Para poder trabajar con los disparadores de postgres se supone se puede hacer directamente una operacion de insert, update o delete, pero nunca lo pude hacer asi que decidi seguir bien el manual de postgres y lo pude conseguir.

Me base en los articulos mencionados, para lo que voy a hacer.


Primero se necesita crear una tabla, en mi caso queria crear una tabla con XML, como lo que ya habia mostrado en mi anterior entrada, pero ahora con el sabor de tener una especie de auditoria sobre la tabla creada propiamente desde la BD y asi no molestar con eso desde el programa, iniciemos:


CREATE TABLE IF NOT EXISTS xml_data
(
  i_id_xml int not null,
  c_tabla_xml text not null,
  c_modificado_xml text not null,
  d_modificado_xml date not null,
  xml_data xml not null,
  PRIMARY KEY (i_id_xml, c_tabla_xml)
);
Listo, ahora la tabla de auditoria que casi no puedo sacar, no sabia que campos poner jejeje, pero creo que con la que cree es mas que suficiente:


CREATE TABLE IF NOT EXISTS auditor_xml_data
(
  i_id_auditor bigserial not null,
  d_cambio_auditoria date not null default NOW(),
  i_id_xml int not null,
  c_tabla_xml text not null,
  c_modificado_xml text not null,
  d_modificado_xml date not null,
  xml_data xml not null,
  PRIMARY KEY (i_id_auditor)
);
Listo, ya tengo mi tabla normal y mi tabla de auditoria con la cual, espero poder hacer algo algun dia, para la creacion del trigger, es necesario crear primero una funcion que se retorne de tipo trigger, algo un poco extraño cuando lo lei, y cuando lo  implemente pero funciona que es lo importante jejejeje:

CREATE OR REPLACE FUNCTION auditoriaXML() RETURNS TRIGGER AS $emp_audit$
  DECLARE
  BEGIN
  IF (TG_OP = 'DELETE') THEN
     insert into auditor_xml_data (i_id_xml, c_tabla_xml, c_modificado_xml, d_modificado_xml, xml_data) values (OLD.*);
  ELSIF (TG_OP = 'UPDATE') THEN
     insert into auditor_xml_data (i_id_xml, c_tabla_xml, c_modificado_xml, d_modificado_xml, xml_data) values (OLD.*);
     END IF;
  RETURN NULL;
  END;
$emp_audit$ LANGUAGE plpgsql;
Bueno, ya con eso se da paso al famoso trigger:

create trigger tr_xml_data after update or delete
on xml_data
FOR EACH ROW
EXECUTE PROCEDURE auditoriaXML();

Explicacion:

create trigger: normal es la parte de poder crear el objeto sobre la BD
tr_xml_data : el nombre del trigger
after update or delete: despues de actualizar o eliminar
on xml_data : sobre la tabla xml_data que creamos anteriormente
for each row: En este caso, pense en dejarlo solo con for each statement que era el por defecto, pero pasa lo siguiente: Cuando se hace con el statement no se tiene acceso a la variable OLD que es quien contiene la informacion del row antes de ser cambiada, asi que me toco con esa.
execute procedure auditoriaXML(): Listo con eso le decimos que debe ejecutar la funcion creada de auditoriaXML();

Hice varias pruebas y todo salio bien, lo unico que me preocupa de esto es cuando la tabla xml_data tenga muchos registros, dado que el trigger hace una lectura de la tabla que hayan cambiado y posterior a eso le ejecuta la funcion. Pero para lo que necesito esta bien.


Listo, los dejo con esa inquietud suerte!!


Documentacion:
http://www.postgresql.org/docs/9.1/static/sql-createtrigger.html
http://www.postgresql.org/docs/current/interactive/plpgsql-trigger.html

Probando las menciones

Probando lo nuevo de plus!! +Vovin Therion

jajaja ya lo puedo joder desde aca!!

11.06.2013

Postgres-XML y JAVA

Estoy probando esta BD para un proyecto que me encuentro realizando, he leido la documentacion de postgres y es en algunos casos incompleta, pero nada que otro ya hubiese tenido que hacer asi que como crear una columna de tipo XML en postgres ahi si es easy dado que solo se coloca como datatype el XML y listo, algo como:

Mi tabla de ejemplo:

CREATE TABLE xml_data ( c_tabla text, c_modificado text, d_modificado date, xml xml )

Como se puede verificar en el script, la columna XML se llama xml, algo creativo pero bueno eso no es lo importante.


>Ahora para la insercion de datos es necesario utilizar una utilidad de postgres llamada XMLPARSE la cual permite realizar el parseo de un documento o de una cadena, para el ejemplo se utilizara una cadena y asi realizar la insercion:

insert into xml_data values ('Departamento', 'Insercion', current_timestamp, XMLPARSE (CONTENT '<departamento><id>05</id><nmDepto>Antioquia</nmDepto></departamento>'));

Por que no le pongo los titulos a donde va la informacion, por pereza, ademas que  la informacion como se envia completa no es necesario agregar los nombres de las columnas donde va la informacion.

Explico el insert:
c_tabla = Departamento
c_modificado = Insercion
d_modificado = current_timestamp (La hora actual de la base de datos)
xml = <departamento><id>05</id><nmDepto>Antioquia</nmDepto></departamento> (Como objeto propio de postgres)


El XML queda de la siguiente forma:
<?xml version="1.0" encoding="UTF-8"?>
<Departamento>
    <id>05</id>
    <nmDepto>Antioquia</nmDepto>
</Departamento>


Asi que con esto ya se tiene una base de datos de tipo noSQL para trabajar y almacenar mucha informacion de cualquier cosa que deseemos guardar.

Ahora la parte que falta la de JAVA, como me traigo esa informacion, es sencillo dado que este objeto XML es devuelto como un Jdbc4SQLXML, esto en otras palabras es que ya es un objeto que podemos leer desde JAVA al momento de tener un resultSet, se puede reflejar en las siguientes lineas:

//Verificando que es un XML de postgres
if (resultSet.getMetaData().getColumnTypeName(i).indexOf("xml") >= 0
                        || resultSet.getMetaData().getColumnType(i) == 209) {
                    //xml 2009  postgres
                    columnXML = i;
                }


//Almacenando el valor de la columna
if (columnXML==i){
                        InputStream is = resultSet.getBinaryStream(i);
                        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
                        String dataXML = s.hasNext() ? s.next() : "";

                        _data.add(dataXML);
                    }else{


Con eso, ya desde JAVA se esta leyendo el XML almacenado en la base de datos.

Bueno, espero el post les sirva tanto como a mi.

Suerte