index java hibernate orm jpa datanucleus

java - index - Especificación de un índice(clave no única) mediante JPA



jpa index (11)

¿Cómo se define un campo, por ejemplo, el email que tiene un índice que utiliza anotaciones JPA? Necesitamos una clave no única en el email porque hay literalmente millones de consultas en este campo por día, y es un poco lento sin la clave.

@Entity @Table(name="person", uniqueConstraints=@UniqueConstraint(columnNames={"code", "uid"})) public class Person { // Unique on code and uid public String code; public String uid; public String username; public String name; public String email; }

He visto una anotación específica de hibernación, pero estoy tratando de evitar soluciones específicas del vendedor, ya que aún estamos decidiendo entre hibernar y datanucleus.

ACTUALIZAR:

A partir de JPA 2.1, puedes hacer esto. Ver: la anotación @Index no está permitida para esta ubicación


Una colección única de anotaciones de índice seleccionadas a mano

= Especificaciones =

= ORM Frameworks =

= ORM para Android =

= Otro (difícil de categorizar) =

  • Realm - Alternative DB para iOS / Android: Annotation io.realm.annotations.Index ;
  • Empire-db : una capa de abstracción de bases de datos relacionales ligera pero poderosa basada en JDBC. No tiene definición de esquema a través de anotaciones;
  • Kotlin NoSQL (GitHub) : una DSL reactiva y segura para tipos para trabajar con bases de datos NoSQL (PoC): ???

Solo opta por uno de ellos.


¡JPA 2.1 (finalmente) agrega soporte para índices y claves externas! Mira blogs.oracle.com/arungupta/entry/jpa_2_1_schema_generation para más detalles. JPA 2.1 es una parte de Java EE 7, que está fuera.

Si le gusta vivir al límite, puede obtener la última instantánea de eclipselink de su repositorio de maven (groupId: org.eclipse.persistence, artifactId: eclipselink, version: 2.5.0-SNAPSHOT). Solo para las anotaciones JPA (que deberían funcionar con cualquier proveedor una vez que sean compatibles con 2.1) use artifactID: javax.persistence, version: 2.1.0-SNAPSHOT.

Lo estoy usando para un proyecto que no estará terminado hasta después de su lanzamiento, y no he notado ningún problema horrible (aunque no estoy haciendo nada demasiado complejo con él).

ACTUALIZACIÓN (26 de septiembre de 2013): hoy en día, las versiones candidatas de lanzamiento y lanzamiento de eclipselink están disponibles en el repositorio central (principal), por lo que ya no es necesario agregar el repositorio eclipselink en los proyectos de Maven. La última versión de lanzamiento es 2.5.0 pero 2.5.1-RC3 también está presente. Cambiaría a 2.5.1 lo antes posible debido a problemas con la versión 2.5.0 (las cosas modelgen no funcionan).


Con JPA 2.1 deberías poder hacerlo.

import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Index; import javax.persistence.Table; @Entity @Table(name = "region", indexes = {@Index(name = "my_index_name", columnList="iso_code", unique = true), @Index(name = "my_index_name2", columnList="name", unique = false)}) public class Region{ @Column(name = "iso_code", nullable = false) private String isoCode; @Column(name = "name", nullable = false) private String name; }

Actualización : si alguna vez necesita crear e indexar con dos o más columnas, puede usar comas. Por ejemplo:

@Entity @Table(name = "company__activity", indexes = {@Index(name = "i_company_activity", columnList = "activity_id,company_id")}) public class CompanyActivity{


EclipseLink proporcionó una anotación (por ejemplo, @Index ) para definir un índice en columnas. Hay un example de su uso. Parte del ejemplo está incluido ...

Los campos firstName y lastName están indexados, juntos e individualmente.

@Entity @Index(name="EMP_NAME_INDEX", columnNames={"F_NAME","L_NAME"}) // Columns indexed together public class Employee{ @Id private long id; @Index // F_NAME column indexed @Column(name="F_NAME") private String firstName; @Index // L_NAME column indexed @Column(name="L_NAME") private String lastName; ... }


En JPA 2.1, debe hacer lo siguiente

import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Index; import javax.persistence.Table; @Entity(name="TEST_PERSON") @Table( name="TEST_PERSON", indexes = { @Index(name = "PERSON_INDX_0", columnList = "age"), @Index(name = "PERSON_INDX_1", columnList = "fName"), @Index(name = "PERSON_INDX_1", columnList = "sName") }) public class TestPerson { @Column(name = "age", nullable = false) private int age; @Column(name = "fName", nullable = false) private String firstName; @Column(name = "sName", nullable = false) private String secondName; @Id private long id; public TestPerson() { } }

En el ejemplo anterior, la tabla TEST_PERSON tendrá 3 índices:

  • índice único en la identificación de la clave principal

  • índice en AGE

  • índice compuesto en FNAME, SNAME

Nota 1: Obtiene el índice compuesto al tener dos anotaciones @Index con el mismo nombre

Nota 2: especifica el nombre de la columna en columnList not the fieldName


Esta solución es para EclipseLink 2.5 y funciona (probado):

@Table(indexes = {@Index(columnList="mycol1"), @Index(columnList="mycol2")}) @Entity public class myclass implements Serializable{ private String mycol1; private String mycol2; }

Esto supone un orden ascendente.


No es posible hacer eso usando la anotación JPA. Y esto tiene sentido: donde una UniqueConstraint define claramente las reglas de un negocio, un índice es solo una forma de acelerar la búsqueda. Entonces esto realmente debería ser hecho por un DBA.


OpenJPA le permite especificar una anotación no estándar para definir el índice en la propiedad.

Los detalles estan here



Por lo que yo sé, no hay una forma cruzada de proveedor de JPA para especificar índices. Sin embargo, siempre puede crearlos a mano directamente en la base de datos, la mayoría de las bases de datos los recogerán automáticamente durante la planificación de consultas.


Realmente me gustaría poder especificar índices de bases de datos de manera estandarizada pero, por desgracia, esto no forma parte de la especificación JPA (tal vez porque la especificación JPA no requiere soporte de generación DDL, que es una especie de bloque de carreteras para tal característica).

Por lo tanto, tendrá que confiar en una extensión específica del proveedor para eso. Hibernate, OpenJPA y EclipseLink claramente ofrecen tal extensión. No puedo confirmar DataNucleus, pero como la definición de los índices forma parte de JDO, creo que sí.

Realmente espero que el soporte de índice se estandarice en las próximas versiones de la especificación y por lo tanto no esté de acuerdo con otras respuestas, no veo ninguna buena razón para no incluir tal cosa en JPA (especialmente porque la base de datos no siempre está bajo su control) para un soporte óptimo de generación de DDL.

Por cierto, sugiero descargar la especificación JPA 2.0.