Looking for jpa Keywords? Try Ask4Keywords

jpaEmpezando con jpa


Observaciones

JPA es la API de persistencia de Java, una especificación que maneja la asignación de objetos Java y sus relaciones con una base de datos relacional. Esto se llama un mapeador objeto-relacional (ORM). Es una alternativa para (o complementar) el JDBC de más bajo nivel. Es más útil cuando se persigue un enfoque orientado a Java y cuando deben persistir gráficos de objetos complejos.

JPA en sí mismo no es una implementación. Necesitará un proveedor de persistencia para eso (ver ejemplos). Las implementaciones actuales del último estándar JPA 2.1 son EclipseLink (también la implementación de referencia para JPA 2.1, que significa "prueba de que la especificación puede implementarse"); Hibernate , y DataNucleus .

Metadatos

La asignación entre los objetos de Java y las tablas de la base de datos se define a través de metadatos de persistencia . El proveedor de JPA utilizará la información de metadatos de persistencia para realizar las operaciones de base de datos correctas. JPA normalmente define los metadatos a través de anotaciones en la clase Java.

Arquitectura de entidad relacional de objetos

La arquitectura de la entidad se compone de:

  • entidades
  • unidades de persistencia
  • contextos de persistencia
  • gestor de entidades fábricas
  • administradores de entidades

Versiones

Versión Grupo de expertos Lanzamiento
1.0 JSR-220 2006-11-06
2.0 JSR-317 2009-12-10
2.1 JSR-338 2013-05-22

Hola Mundo

Veamos todos los componentes básicos para crear un simple Hallo World.

  1. Definir qué implementación de JPA 2.1 usaremos
  2. Construye la conexión a la base de datos creando la persistence-unit
  3. Implementa las entidades.
  4. Implementa DAO (objeto de acceso a datos) para manipular las entidades.
  5. Probar la aplicación

Bibliotecas

Usando maven, necesitamos estas dependencias:

<dependencies>

    <!-- JPA is a spec, I'll use the implementation with HIBERNATE -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.6.Final</version>
    </dependency>

    <!-- JDBC Driver, use in memory DB -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.193</version>
    </dependency>

</dependencies>
 

Unidad de Persistencia

En la carpeta de recursos necesitamos crear un archivo llamado persistence.xml . La forma más fácil de definirlo es así:

<persistence-unit name="hello-jpa-pu" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <properties>
        <!-- ~ = relative to current user home directory -->
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:./test.db"/>
        <property name="javax.persistence.jdbc.user" value=""/>
        <property name="javax.persistence.jdbc.password" value=""/>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
        <property name="hibernate.show_sql" value="true"/>

        <!-- This create automatically the DDL of the database's table -->
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

    </properties>
</persistence-unit>
 

Implementar una entidad

Creo un Biker clase:

package it.hello.jpa.entities;


import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "BIKER")
public class Biker implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "bikerName")
    private String name;

    @Column(unique = true, updatable = false)
    private String battleName;

    private Boolean beard;

    @Temporal(TemporalType.DATE)
    private Date birthday;

    @Temporal(TemporalType.TIME)
    private Date registrationDate;

    @Transient // --> this annotiation make the field transient only for JPA
    private String criminalRecord; 

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBattleName() {
        return battleName;
    }

    public void setBattleName(String battleName) {
        this.battleName = battleName;
    }

    public Boolean getBeard() {
        return this.beard;
    }

    public void setBeard(Boolean beard) {
        this.beard = beard;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

    public String getCriminalRecord() {
        return criminalRecord;
    }

    public void setCriminalRecord(String criminalRecord) {
        this.criminalRecord = criminalRecord;
    }
}
 

Implementar un DAO

package it.hello.jpa.business;

import it.hello.jpa.entities.Biker;

import javax.persistence.EntityManager;
import java.util.List;

public class MotorcycleRally {

    public Biker saveBiker(Biker biker) {
        EntityManager em = EntityManagerUtil.getEntityManager();
        em.getTransaction().begin();
        em.persist(biker);
        em.getTransaction().commit();
        return biker;
    }

}
 

EntityManagerUtil es un singleton:

package it.hello.jpa.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EntityManagerUtil {

    // USE THE SAME NAME IN persistence.xml!
    public static final String PERSISTENCE_UNIT_NAME = "hello-jpa-pu";

    private static EntityManager entityManager;

    private EntityManagerUtil() {
    }

    public static EntityManager getEntityManager() {
        if (entityManager == null) {
            // the same in persistence.xml
            EntityManagerFactory emFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);


            return emFactory.createEntityManager();
        }
        return entityManager;
    }
}
 

Probar la aplicación

paquete it.hello.jpa.test;

clase pública TestJpa {

@Test
public void insertBiker() {
    MotorcycleRally crud = new MotorcycleRally();

    Biker biker = new Biker();
    biker.setName("Manuel");
    biker.setBeard(false);

    biker = crud.saveBiker(biker);

    Assert.assertEquals(biker.getId(), Long.valueOf(1L));
}
 

}

La salida será:

Ejecutando it.hello.jpa.test.TestJpa Hibernate: descarte la tabla BIKER si existe Hibernate: suelte la secuencia si existe hibernate_sequence Hibernate: cree la secuencia hibernate_sequence comience con 1 incremento por 1 Hibernate: cree la tabla BIKER (id bigint not null, battleName varchar (255) ), barba booleana, fecha de cumpleaños, nombre del motorista varchar (255), hora de registro de fecha, clave principal (id) Hibernar: modificar tabla BIKER agregar restricción UK_a64ce28nywyk8wqrvfkkuapli unique (battleName), hibernar: insertar en BIKER (battleName, beard, cumpleaños, bikerName, registro , id) valores (?,?,?,?,?,?) mar 01, 2017 11:00:02 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [nombre: hello- Resultados de jpa-pu ...

Las pruebas ejecutan: 1, fallas: 0, errores: 0, omitidos: 0

Instalación o configuración

Requisitos de classpath

Eclipselink

Es necesario incluir Eclipselink y JPA API. Ejemplo de dependencias de Maven:

<dependencies>
  <dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.6.3</version>
  </dependency>
  <dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>javax.persistence</artifactId>
    <version>2.1.1</version>
  </dependency>
  <!-- ... -->
</dependencies>
 

Hibernar

Hibernate-core es obligatorio. Ejemplo de dependencia de Maven:

<dependencies>
  <dependency>
    <!-- requires Java8! -->
    <!-- as of 5.2, hibernate-entitymanager is merged into hibernate-core -->
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.1.Final</version>
  </dependency>
  <dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0</version>
  </dependency>
  <!-- ... -->
</dependencies>
 

DataNucleus

Se requieren datanucleus-core, datanucleus-api-jpa y datanucleus-rdbms (cuando se usan almacenes de datos RDBMS). Ejemplo de dependencia de Maven:

<dependencies>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>5.0.0-release</version>
  </dependency>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-api-jpa</artifactId>
    <version>5.0.0-release</version>
  </dependency>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-rdbms</artifactId>
    <version>5.0.0-release</version>
  </dependency>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>javax.persistence</artifactId>
    <version>2.1.2</version>
  </dependency>
  <!-- ... -->
</dependencies>
 

Detalles de configuración

JPA requiere el uso de un archivo persistence.xml , ubicado bajo META-INF desde la raíz de CLASSPATH. Este archivo contiene una definición de las unidades de persistencia disponibles desde las cuales JPA puede operar.

JPA además permite el uso de un archivo de configuración de mapeo orm.xml , también ubicado en META-INF . Este archivo de asignación se usa para configurar cómo se asignan las clases al almacén de datos, y es una alternativa / complemento al uso de las anotaciones de Java en las propias clases de entidad JPA.

Ejemplo de persistencia mínima.xml

Hibernar (y incrustado H2 DB)

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1.xsd"
         version="2.1">

<persistence-unit name="persistenceUnit">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <class>my.application.entities.MyEntity</class>
    
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> 
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:data/myDB.db" /> 
        <property name="javax.persistence.jdbc.user" value="sa" /> 

        <!-- DDL change options -->
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>

        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
        <property name="hibernate.flushMode" value="FLUSH_AUTO" /> 
    </properties>
</persistence-unit>
</persistence>
 

Eclipselink (y H2 DB incrustada)

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1.xsd"
         version="2.1">

<persistence-unit name="persistenceUnit">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

    <class>my.application.entities.MyEntity</class>
    
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:data/myDB.db"/>
        <property name="javax.persistence.jdbc.user" value="sa"/>

        <!-- Schema generation : drop and create tables -->
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create-tables" />
    </properties>
</persistence-unit>

</persistence>
 

DataNucleus (y DB H2 incrustado)

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1.xsd"
         version="2.1">

<persistence-unit name="persistenceUnit">
    <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>

    <class>my.application.entities.MyEntity</class>
    
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:data/myDB.db"/>
        <property name="javax.persistence.jdbc.user" value="sa"/>

        <!-- Schema generation : drop and create tables -->
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create-tables" />
    </properties>
</persistence-unit>

</persistence>