lunes, 19 de diciembre de 2011

Introducción JPA- Java Persistence API


Hace algún tiempo había leído bastante sobre JPA, incluso antes de que naciera JPA tuve que trabajar con EJB 2.0 así que una de las cosas interesantes sobre ORM (Object Relational Mapping) están en JPA.


Con EJB 2.0 resultaba bastante incómodo trabajar con los ficheros xml de configuración, las diferentes interfaces local, remota y el propio bean, con JPA y las anotaciones de JAVA esto desaparece, pero no voy a correr tanto, en este artículo me voy a limitar a hablar de JPA, usando un ejemplo sencillo y usando la implementación que hace hibernate de JPA.


He utilizado la siguiente tecnología:
  • MySQL 5.1.xx
  • MySQL workbench
  • Eclipse Indigo
  • JAVA SE 7
  • JBOSS 5.0.1


Definición:


Antes de nada comentar que es JPA. Según la definición de la wikipedia:


Es la API de persistencia desarrollada para la plataforma Java EE
Es un framework del lenguaje de programación Java que maneja datos relacionales en aplicaciones usando la Plataforma Java en sus ediciones Standard (Java SE) y Enterprise (Java EE).
La JPA fue originada a partir del trabajo del JSR 220 Expert Group. Ha sido incluida en el estándar EJB3.
Persistencia en este contexto cubre tres áreas:
  • La API en sí misma, definida en javax.persistence.package
  • La Java Persistence Query Language (JPQL)
  • Metadatos objeto/relacional
El objetivo que persigue el diseño de esta API es no perder las ventajas de la orientación a objetos al interactuar con una base de datos (siguiendo el patrón de mapeo objeto-relacional), como sí pasaba con EJB2, y permitir usar objetos regulares (conocidos como POJOs).






El ejemplo:


Aunque he empezado primero creando las tablas en un esquema “JPA”, dentro de mysql, podría haber empezado cranto los beans de java y con estos establecer una conexión a MySql y se habrían creado de todas formas.


  • He creado las siguientes tablas con MySQL workbench (conectando a MySQL y generando las tablas):

  • Usando las funciones JPA de eclipse, he creado un proyecto de tipo JPA, y creado los beans entity usando la función “JPA entities from tables”, al final el código generado es el siguiente:


Departament.java:


package jpa.beans;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Set;
/**
* The persistent class for the Departament database table.
*
*/
@Entity
public class Departament implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int idDepartament;
private String name;
//bi-directional many-to-one association to Person
@OneToMany(mappedBy="departament")
private Set<Person> persons;
public Departament() {
}
public int getIdDepartament() {
return this.idDepartament;
}
public void setIdDepartament(int idDepartament) {
this.idDepartament = idDepartament;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set<Person> getPersons() {
return this.persons;
}
public void setPersons(Set<Person> persons) {
this.persons = persons;
}
}


Person.java:


package jpa.beans;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the Person database table.
*
*/
@Entity
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private PersonPK id;
private String address;
private String country;
@Column(name="`first name`")
private String first_name;
@Column(name="`last name`")
private String last_name;
@Column(name="`zip code`")
private String zip_code;
//bi-directional many-to-one association to Departament
@ManyToOne
@JoinColumn(name="Departament_idDepartament",insertable=false,updatable=false)
private Departament departament;
public Person() {
}
public PersonPK getId() {
return this.id;
}
public void setId(PersonPK id) {
this.id = id;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCountry() {
return this.country;
}
public void setCountry(String country) {
this.country = country;
}
public String getFirst_name() {
return this.first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return this.last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getZip_code() {
return this.zip_code;
}
public void setZip_code(String zip_code) {
this.zip_code = zip_code;
}
public Departament getDepartament() {
return this.departament;
}
public void setDepartament(Departament departament) {
this.departament = departament;
}
}
PersonPK.java:
package jpa.beans;
import java.io.Serializable;
import javax.persistence.*;
/**
* The primary key class for the Person database table.
*
*/
@Embeddable
public class PersonPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
private int idPerson;
@Column(name="Departament_idDepartament")
private int departament_idDepartament;
public PersonPK() {
}
public int getIdPerson() {
return this.idPerson;
}
public void setIdPerson(int idPerson) {
this.idPerson = idPerson;
}
public int getDepartament_idDepartament() {
return this.departament_idDepartament;
}
public void setDepartament_idDepartament(int departament_idDepartament) {
this.departament_idDepartament = departament_idDepartament;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof PersonPK)) {
return false;
}
PersonPK castOther = (PersonPK)other;
return
(this.idPerson == castOther.idPerson)
&& (this.departament_idDepartament == castOther.departament_idDepartament);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.idPerson;
hash = hash * prime + this.departament_idDepartament;
return hash;
}
}
  • Hice un pequeño Main de pruebas:


package jpa.main;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import jpa.beans.Departament;
public class Main {
public static void main(String args[])throws Exception{
EntityManagerFactory emf=Persistence.createEntityManagerFactory("JPATestJv");
EntityManager em=emf.createEntityManager();
try{
EntityTransaction entr=em.getTransaction();
entr.begin();
Departament dep = new Departament();
dep.setIdDepartament(0);
dep.setName("Marketing");
dep.setPersons(null);
em.persist(dep);
entr.commit();
}finally{
em.close();
}
}
}
  • El fichero persistence.xml:


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="JPATestJv" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>jpa.beans.Departament</class>
<class>jpa.beans.Person</class>
<class>jpa.beans.PersonPK</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/JPA"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.password" value="JPA"/>
<property name="hibernate.connection.username" value="JPA"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>




  • El resultado de la ejecución del Main:


Hibernate: insert into Departament (name, idDepartament) values (?, ?)


  • Después se realiza la select para ver si se han insertado los datos:


mysql> select * from Departament;
+---------------+-----------+
| idDepartament | name |
+---------------+-----------+
| 0 | Marketing |
+---------------+-----------+
1 row in set (0.00 sec)

1 comentario: