Spécification d’un index (clé non unique) à l’aide de JPA

Comment définissez-vous un champ, par exemple un email ayant un index utilisant des annotations JPA. Nous avons besoin d’une clé non unique sur le email car il y a littéralement des millions de requêtes par jour sur ce champ, et c’est un peu lent sans la clé.

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

J’ai vu une annotation spécifique à la mise en veille prolongée, mais j’essaie d’éviter les solutions spécifiques aux fournisseurs, car nous sums toujours en train de décider entre hibernate et datanucleus.

METTRE À JOUR:

A partir de JPA 2.1, vous pouvez le faire. Voir: l’annotation @Index n’est pas autorisée pour cet emplacement

Pour autant que je sache, il n’y a pas de méthode cross-JPA-Provider pour spécifier les index. Cependant, vous pouvez toujours les créer à la main directement dans la firebase database, la plupart des bases de données les récupéreront automatiquement lors de la planification des requêtes.

Avec JPA 2.1, vous devriez pouvoir le faire.

 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 Ssortingng isoCode; @Column(name = "name", nullable = false) private Ssortingng name; } 

Mise à jour : Si vous devez créer et indexer avec deux colonnes ou plus, vous pouvez utiliser des virgules. Par exemple:

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

JPA 2.1 (enfin) ajoute la prise en charge des index et des clés étrangères! Voir ce blog pour plus de détails. JPA 2.1 fait partie de Java EE 7, qui est sorti.

Si vous aimez vivre sur le bord, vous pouvez obtenir le dernier instantané pour eclipselink à partir de leur repository maven (groupId: org.eclipse.persistence, artifactId: eclipselink, version: 2.5.0-SNAPSHOT). Pour seulement les annotations JPA (qui devraient fonctionner avec n’importe quel fournisseur une fois qu’elles prennent en charge 2.1), utilisez artefactID: javax.persistence, version: 2.1.0-SNAPSHOT.

Je l’utilise pour un projet qui ne sera terminé qu’après sa sortie, et je n’ai pas remarqué de problèmes horribles (bien que je ne fasse rien de trop complexe).

MISE À JOUR (26 sept. 2013): De nos jours, les versions candidates à la publication et à la libération d’eclipselink sont disponibles dans le référentiel central (principal). Vous n’avez donc plus besoin d’append le référentiel eclipselink dans les projets Maven. La version la plus récente est la version 2.5.0 mais la version 2.5.1-RC3 est également présente. Je passerais à la version 2.5.1 ASAP en raison de problèmes avec la version 2.5.0 (les éléments modelgen ne fonctionnent pas).

Une collection unique et annotée d’annotations d’index

= Spécifications =

  • JPA 2.1+: javax.persistence.Index (ou voir JSR-000338 PDF, p. 452, élément 11.1.23)
    L’annotation JPA @Index ne peut être utilisée que dans le cadre d’une autre annotation comme @Table , @SecondaryTable , etc.:

     @Table(indexes = { @Index(...) }) 
  • JDO 2.1+: javax.jdo.annotations.Index

= Cadres ORM =

  • ♥ Hibernate ORM : org.hibernate.annotations.Index ;
  • OpenJPA : org.apache.openjpa.persistence.jdbc.Index et org.apache.openjpa.persistence.jdbc.ElementIndex (voir le Guide de référence );
  • EclipseLink : org.eclipse.persistence.annotations.Index ;
  • DataNucleus : org.datanucleus.api.jpa.annotations.Index ;
  • Carbonado (GitHub) : com.amazon.carbonado.Index ;
  • EBean : com.avaje.ebean.annotation.Index ou io.ebean.annotation.Index?
  • Ujorm : Annotation org.ujorm.orm.annot.Column , index et uniqueIndex propriétés;
  • Requery ( GitHub . Java, Kotlin, Android): Annotation io.requery.Index ;
  • Exposé (Bibliothèque SQL Kotlin ): org.jetbrains.exposed.sql.Index , org.jetbrains.exposed.sql.Table # index () . Exemple:

     object Persons : IdTable() { val code = varchar("code", 50).index() } 

= ORM pour Android =

  • ♥ ActiveAndroid : Annotation com.activeandroid.annotation.Column a les com.activeandroid.annotation.Column index , indexGroups , unique et uniqueGroups ;
    MISE À JOUR [2018]: ActiveAndroid était un bon ORM il y a 4 ans, mais malheureusement, l’auteur de la bibliothèque a cessé de le gérer, alors quelqu’un a bricolé, corrigé les bogues, et l’a rebaptisé ReActiveAndroid . Reportez-vous au Guide de migration si vous souhaitez remplacer ActiveAndroid dans un projet hérité.
  • ReActiveAndroid : Annotation com.reactiveandroid.annotation.Column a les com.reactiveandroid.annotation.Column index , indexGroups , unique et uniqueGroups ;
  • ORMLite : Annotation com.j256.ormlite.field.DatabaseField a une propriété d’ index ;
  • greenDAO : org.greenrobot.greendao.annotation.Index ;
  • ORMAN (GitHub) : org.orman.mapper.annotation.Index ;
  • ★ DBFlow (GitHub) : com.raizlabs.android.dbflow.sql.index.Index ( exemple d’utilisation);
  • autre

= Autre (difficile à classer) =

  • Realm – Alternative DB pour iOS / Android: Annotation io.realm.annotations.Index ;
  • Empire-db – une couche d’abstraction de firebase database relationnelle légère mais puissante, basée sur JDBC. Il n’a pas de définition de schéma par des annotations;
  • Kotlin NoSQL (GitHub) – un DSL réactif et sécurisé pour travailler avec des bases de données NoSQL (PoC): ???

Allez-y pour l’un d’entre eux.

J’aimerais vraiment pouvoir spécifier des index de firebase database de manière standardisée, mais malheureusement, cela ne fait pas partie de la spécification JPA (peut-être parce que la spécification JPA ne requirejs pas la prise en charge de la génération DDL une telle caractéristique).

Donc, vous devrez compter sur une extension spécifique au fournisseur pour cela. Hibernate, OpenJPA et EclipseLink offrent clairement une telle extension. Je ne peux pas confirmer pour DataNucleus mais puisque la définition des index fait partie de JDO, je suppose que c’est le cas.

J’espère vraiment que la prise en charge de l’index sera standardisée dans les prochaines versions de la spécification et donc en désaccord avec les autres réponses, je ne vois aucune raison de ne pas l’inclure dans JPA (d’autant plus que la firebase database n’est pas toujours sous votre contrôle) pour une prise en charge optimale de la génération de DDL.

En passant, je suggère de télécharger la spécification JPA 2.0.

Dans JPA 2.1, vous devez effectuer les opérations suivantes

 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 Ssortingng firstName; @Column(name = "sName", nullable = false) private Ssortingng secondName; @Id private long id; public TestPerson() { } } 

Dans l’exemple ci-dessus, la table TEST_PERSON aura 3 index:

  • index unique sur l’ID de clé primaire

  • index sur AGE

  • index composé sur FNAME, SNAME

Note 1: Vous obtenez l’index composé en ayant deux annotations @Index du même nom

Remarque 2: vous spécifiez le nom de la colonne dans la liste des colonnes et non le nom du champ

EclipseLink a fourni une annotation (par exemple, @Index ) pour définir un index sur les colonnes. Il y a un exemple de son utilisation. Une partie de l’exemple est incluse …

Les champs firstName et lastName sont indexés, ensemble et individuellement.

 @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 Ssortingng firstName; @Index // L_NAME column indexed @Column(name="L_NAME") private Ssortingng lastName; ... } 

OpenJPA vous permet de spécifier des annotations non standard pour définir un index sur la propriété.

Les détails sont ici .

Pour résumer les autres réponses:

  • Hibernate: org.hibernate.annotations.Index
  • OpenJPA: org.apache.openjpa.persistence.jdbc.Index
  • EclipseLink: org.eclipse.persistence.annotations.Index

Je voudrais juste aller pour l’un d’eux. Il viendra de toute façon avec JPA 2.1 et ne devrait pas être trop difficile à modifier si vous souhaitez réellement changer de fournisseur JPA.

Cela n’est pas possible en utilisant les annotations JPA. Et cela a du sens: lorsqu’une UniqueConstraint définit clairement une règle métier, un index est juste un moyen de rendre la recherche plus rapide. Donc, cela devrait vraiment être fait par un DBA.

Cette solution est pour EclipseLink 2.5 et fonctionne (testée):

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

Cela suppose un ordre croissant.