Specifying an Index (Non-Unique Key) Using JPA

How do you define a field, eg email as having an index using JPA annotations. We need a non-unique key on email because there are literally millions of queries on this field per day, and its a bit slow without the key.

@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;
}

I have seen a hibernate specific annotation but I am trying to avoid vendor specific solutions as we are still deciding between hibernate and datanucleus.

UPDATE:

As of JPA 2.1, you can do this. See: The annotation @Index is disallowed for this location


With JPA 2.1 you should be able to do it.

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;

} 

Update: If you ever need to create and index with two or more columns you may use commas. For example:

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

A unique hand-picked collection of Index annotations

= Specifications =

  • JPA 2.1+: javax.persistence.Index (or see JSR-000338 PDF, p. 452, item 11.1.23)
    The JPA @Index annotation can only be used as part of another annotation like @Table, @SecondaryTable, etc.:

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

= ORM Frameworks =

  • ♥ Hibernate ORM: org.hibernate.annotations.Index;
  • OpenJPA: org.apache.openjpa.persistence.jdbc.Index and org.apache.openjpa.persistence.jdbc.ElementIndex (see Reference Guide);
  • 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 or io.ebean.annotation.Index ?
  • Ujorm: Annotation org.ujorm.orm.annot.Column, index and uniqueIndex properties;
  • requery (GitHub. Java, Kotlin, Android): Annotation io.requery.Index;
  • Exposed (Kotlin SQL Library): org.jetbrains.exposed.sql.Index, org.jetbrains.exposed.sql.Table#index(). Example:

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

= ORM for Android =

  • ♥ ActiveAndroid: Annotation com.activeandroid.annotation.Column has index, indexGroups, unique, and uniqueGroups properties;
    UPDATE [2018]: ActiveAndroid was a nice ORM 4 years ago, but unfortunately, the author of the library stopped maintaining it, so someone forked, fixed bugs, and rebranded it as ReActiveAndroid - use this if you're starting a new project or refer to Migration Guide if you want to replace ActiveAndroid in a legacy project.
  • ReActiveAndroid: Annotation com.reactiveandroid.annotation.Column has index, indexGroups, unique, and uniqueGroups properties;
  • ORMLite: Annotation com.j256.ormlite.field.DatabaseField has an index property;
  • greenDAO: org.greenrobot.greendao.annotation.Index;
  • ORMAN (GitHub): org.orman.mapper.annotation.Index;
  • ★ DBFlow (GitHub): com.raizlabs.android.dbflow.sql.index.Index (example of usage);
  • other (lots of ORM libraries at the Android Arsenal).

= Other (difficult to categorize) =

  • Realm - Alternative DB for iOS / Android: Annotation io.realm.annotations.Index;
  • Empire-db - a lightweight yet powerful relational DB abstraction layer based on JDBC. It has no schema definition through annotations;
  • Kotlin NoSQL (GitHub) - a reactive and type-safe DSL for working with NoSQL databases (PoC): ???
  • Slick - Reactive Functional Relational Mapping for Scala. It has no schema definition through annotations.

Just go for one of them.