Specifying an Index (Non-Unique Key) Using JPA

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.


JPA 2.1 (finally) adds support for indexes and foreign keys! See this blog for details. JPA 2.1 is a part of Java EE 7, which is out .

If you like living on the edge, you can get the latest snapshot for eclipselink from their maven repository (groupId:org.eclipse.persistence, artifactId:eclipselink, version:2.5.0-SNAPSHOT). For just the JPA annotations (which should work with any provider once they support 2.1) use artifactID:javax.persistence, version:2.1.0-SNAPSHOT.

I'm using it for a project which won't be finished until after its release, and I haven't noticed any horrible problems (although I'm not doing anything too complex with it).

UPDATE (26 Sep 2013): Nowadays release and release candidate versions of eclipselink are available in the central (main) repository, so you no longer have to add the eclipselink repository in Maven projects. The latest release version is 2.5.0 but 2.5.1-RC3 is also present. I'd switch over to 2.5.1 ASAP because of issues with the 2.5.0 release (the modelgen stuff doesn't work).