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
andorg.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
anduniqueIndex
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
hasindex
,indexGroups
,unique
, anduniqueGroups
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
hasindex
,indexGroups
,unique
, anduniqueGroups
properties; -
ORMLite: Annotation
com.j256.ormlite.field.DatabaseField
has anindex
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.