Google Code disponible en: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
El API de persistencia de Java (JPA) es una interfaz estándar para almacenar objetos que contienen datos en una base de datos relacional. El estándar define interfaces para la anotación de objetos Java, la recuperación de objetos a través de consultas y la interacción con una base de datos a través de transacciones. Una aplicación que utiliza la interfaz JPA puede funcionar con diferentes bases de datos sin utilizar un código de bases de datos específico del proveedor. JPA permite que tu aplicación migre fácilmente entre diferentes proveedores de bases de datos.
El SDK de Java de App Engine incluye una implementación de JPA 1.0 para el almacén de datos de App Engine. La implementación está basada en DataNucleus Access Platform. Puesto que JPA presenta una interfaz estándar para interactuar con bases de datos relacionales, la implementación App Engine no admite algunas funciones de JPA. Hemos hecho todo lo posible para informar de estas funciones siempre que sea posible.
Para obtener más información sobre JPA, consulta la documentación de Access Platform 1.1. En concreto, consulta "JPA Mapping" (Asignación de JPA) y "JPA API" (API JPA).
Para utilizar JPA y acceder al almacén de datos, una aplicación App Engine necesita lo siguiente:
war/WEB-INF/lib/ de la aplicación.persistence.xml debe estar en el directorio war/WEB-INF/classes/META-INF/ de la aplicación, junto con configuración que indica a JPA el uso del almacén de datos de App Engine.Si utilizas el complemento de Google para Eclipse, debes tener en cuenta el primer y tercer elemento. El nuevo asistente de proyecto guarda los JAR del almacén de datos y de JPA en la ubicación correcta y el proceso de compilación realiza el paso de "mejora" de forma automática. Debes crear persistence.xml de forma manual y guardarlo en war/WEB-INF/classes/META-INF/. El complemento se actualizará en breve para poder realizar esto también de forma automática.
Si utilizas Apache Ant para crear tu proyecto, puedes utilizar una tarea de Ant incluida en el SDK para realizar el paso de mejora. Si configuras tu proyecto, debes copiar los JAR y crear el archivo de configuración. Para obtener más información sobre la tarea de Ant, consulta Uso de Apache Ant.
Los JAR del almacén de datos y de JPA se incluyen en el SDK de Java de App Engine. Los puedes encontrar en el directorio appengine-java-sdk/lib/user/orm/.
Copia los JAR en el directorio war/WEB-INF/lib/ de tu aplicación.
Asegúrate de que el JAR appengine-api.jar también esté en el directorio war/WEB-INF/lib/. (Es posible que ya lo hayas copiado al crear el proyecto). El complemento de DataNucleus de App Engine utiliza este JAR para acceder al almacén de datos.
La interfaz JPA necesita un archivo de configuración llamado persistence.xml en el directorio war/WEB-INF/classes/META-INF/ de la aplicación. Puedes crear este archivo directamente en esta ubicación o copiarlo del directorio de origen durante el proceso de compilación.
Crea el archivo con el contenido que se muestra a continuación:
<?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_1_0.xsd" version="1.0">
<persistence-unit name="transactions-optional">
<provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
</properties>
</persistence-unit>
</persistence>
La implementación DataNucleus de JPA utiliza un paso de "mejora" de la post-compilación durante el proceso de compilación para asociar clases de datos a la implementación JPA.
Si utilizas Apache Ant, el SDK incluye una tarea de Ant para realizar este paso. Para obtener más información sobre la tarea de Ant, consulta Uso de Apache Ant.
Puedes realizar el paso de mejora en clases compiladas de la línea de comandos con el siguiente comando:
java -cp classpath org.datanucleus.enhancer.DataNucleusEnhancer class-files
La ruta de clase deberá contener los JAR datastore-core-*.jar, datanucleus-enhancer-*.jar, asm-*.jar y geronimo-jpa-*.jar (en los que * es el número de versión adecuado de cada JAR) del directorio appengine-java-sdk/lib/tools/, así como de las clases de datos.
Para obtener más información sobre el mejorador de código de bytes de DataNucleus, consulta la documentación de DataNucleus.
Una aplicación interactúa con JPA a través de una instancia de la clase EntityManager. Esta se obtiene a través de la creación de una instancia y de la ejecución de un método en una instancia de la clase EntityManagerFactory. El método predeterminado utiliza la configuración de JPA (identificada por el nombre "transactions-optional") para crear instancias EntityManager.
Puesto que una instancia EntityManagerFactory tarda en inicializarse, sería recomendable reutilizar una única instancia en la medida de lo posible. Una forma sencilla de hacer esto es crear una clase envoltorio singleton con una instancia estática, como se muestra a continuación:
EMF.java
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public final class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("transactions-optional");
private EMF() {}
public static EntityManagerFactory get() {
return emfInstance;
}
}
La aplicación utiliza la instancia de un método predeterminado para crear una instancia EntityManager para cada solicitud que accede al almacén de datos.
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import EMF;
// ...
EntityManager em = EMF.get().createEntityManager();
Utiliza el EntityManager para almacenar, actualizar y eliminar objetos de datos, así como para realizar consultas de almacén de datos.
Cuando termines con la instancia EntityManager, debes ejecutar el método close(). Es un error utilizar la instancia EntityManager después de ejecutar el método close().
try {
// ... do stuff with em ...
} finally {
em.close();
}
Cada objeto guardado por JPA se convierte en una entidad en el almacén de datos de App Engine. Este tipo de entidad deriva del nombre sencillo de la clase (sin el nombre de paquete). Cada campo persistente de la clase representa una propiedad de la entidad, en la que el nombre de la propiedad es igual al nombre del campo (respetando mayúsculas y minúsculas).
Para declarar que una clase Java puede almacenarse y recuperarse del almacén de datos a través de JPA, asigna a la clase una anotación @Entity. Por ejemplo:
import javax.persistence.Entity;
@Entity
public class Employee {
// ...
}
Los campos de la clase de datos almacenados en el almacén de datos deben ser de un tipo persistente de forma predeterminada o declarado de forma explícita como persistente. Puedes encontrar una tabla que detalla el comportamiento de persistencia predeterminado en el sitio web de DataNucleus. Para declarar de forma explícita un campo como persistente, normalmente se le asignaría una anotación @Basic, pero en la actualidad se produce un error que evita que esto funcione. Así que, como solución, puedes utilizar la anotación @Enumerated en su lugar.
import java.util.Date;
import javax.persistence.Enumerated;
import com.google.appengine.api.datastore.ShortBlob;
// ...
@Enumerated
private ShortBlob data;
El tipo de campo puede ser cualquiera de los siguientes:
java.util.List<...>) de valores de tipo principal del almacén de datos,@Entity,Una clase de datos debe tener un constructor predeterminado protegido o público, así como un campo dedicado a almacenar la clave principal de la entidad de almacén de datos correspondiente. Puedes elegir entre 4 tipos diferentes de campos de clave, cada uno de los cuales utiliza un tipo de valor y unas anotaciones diferentes. (Para obtener más información, consulta Creación de datos: claves). El campo de clave más sencillo consiste en un valor entero largo que JPA rellena de forma automática con un valor exclusivo para todas las demás instancias de la clase al guardar el objeto en el almacén de datos por primera vez. Las claves enteras largas utilizan una anotación @Id y una anotación @GeneratedValue(strategy = GenerationType.IDENTITY):
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
// ...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
A continuación se muestra un ejemplo de una clase de datos:
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private Date hireDate;
// Accessors for the fields. JPA doesn't use these, but your application does.
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
}
Las siguientes funciones de la interfaz JPA no son compatibles con la implementación App Engine: