Указание индекса (не-уникальный ключ) с использованием JPA

Как вы определяете поле, например email как имеющее индекс, используя аннотации JPA. Нам нужен не уникальный ключ на email, потому что в этом поле в буквальном смысле миллионы запросов в день, и он немного медленнее без ключа.

@Entity
@Table(name="person", 
       [email protected](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;
}

Я видел аннотацию спящего режима, но я стараюсь избегать конкретных решений для поставщиков, поскольку мы все еще решаем между спящим и datanucleus.

UPDATE:

Как и в JPA 2.1, вы можете это сделать. См.: Аннотации @Index запрещены для этого местоположения

Ответ 1

Насколько я знаю, не существует метода перекрестного JPA-провайдера для указания индексов. Однако вы всегда можете создавать их вручную непосредственно в базе данных, большинство баз данных автоматически подбирают их во время планирования запросов.

Ответ 2

С JPA 2.1 вы сможете это сделать.

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;

} 

Обновление. Если вам нужно создавать и индексировать два или более столбца, вы можете использовать запятые. Например:

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

Ответ 3

JPA 2.1 (наконец) добавляет поддержку индексов и внешних ключей! Подробнее см. этот блог. JPA 2.1 является частью Java EE 7, который отсутствует.

Если вам нравится жить на краю, вы можете получить последний снимок для eclipselink из своего репозитория maven (groupId: org.eclipse.persistence, artifactId: eclipselink, версия: 2.5.0-SNAPSHOT). Только для JPA-аннотаций (которые должны работать с любым провайдером, когда они поддерживают 2.1) используйте artifactID: javax.persistence, version: 2.1.0-SNAPSHOT.

Я использую его для проекта, который не будет завершен до его выпуска, и я не заметил никаких ужасных проблем (хотя я не делаю с ним ничего сложного).

UPDATE (26 сентября 2013 г.). В настоящее время выпуски и выпуски потенциальных версий eclipselink доступны в центральном (основном) репозитории, поэтому вам больше не нужно добавлять репозиторий eclipselink в проекты Maven. Последняя версия версии 2.5.0, но присутствует 2.5.1-RC3. Я переключился на 2.5.1 ASAP из-за проблем с выпуском версии 2.5.0 (файл modelgen не работает).

Ответ 4

Уникальная сборная коллекция аннотаций индекса

= Технические характеристики =

  • JPA 2.1+: javax.persistence.Index (или см. JSR-000338, стр. 450, п. 11.1.23)
    Аннотацию JPA @Index можно использовать только как часть другой аннотации, такой как @Table, @SecondaryTable и т.д.:

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

= ORM Рамки =

= ORM для Android=

= Другое (трудно классифицировать) =

  • Realm - Альтернативная БД для iOS/Android: аннотация io.realm.annotations.Index;
  • Empire-db - легкий, но мощный реляционный уровень абстракции DB на основе JDBC. Он не имеет определения схемы через аннотации;
  • Kotlin NoSQL (GitHub) - реактивный и безопасный по типу DSL для работы с базами данных NoSQL (PoC):

Просто пойдите для одного из них.

Ответ 5

Я бы очень хотел, чтобы можно было указывать индексы базы данных стандартизованным способом, но, к сожалению, это не является частью спецификации JPA (возможно, потому что поддержка генерации DDL не требуется спецификацией JPA, что является своего рода дорожный блок для такой функции).

Таким образом, для этого вам придется полагаться на расширение для провайдера. Hibernate, OpenJPA и EclipseLink явно предлагают такое расширение. Я не могу подтвердить DataNucleus, но поскольку определение индексов является частью JDO, я предполагаю, что это действительно так.

Я очень надеюсь, что поддержка индексов будет стандартизирована в следующих версиях спецификации и, следовательно, каким-то образом не согласуется с другими ответами, я не вижу веских оснований не включать такую ​​вещь в JPA (тем более, что база данных не всегда находится под ваш контроль) для оптимальной поддержки генерации DDL.

Кстати, я предлагаю загрузить спецификацию JPA 2.0.

Ответ 6

В JPA 2.1 вам нужно сделать следующее

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() {
    }
}

В приведенном выше примере таблица TEST_PERSON будет иметь 3 индекса:

  • уникальный индекс идентификатора первичного ключа

  • index on AGE

  • составной индекс в FNAME, SNAME

Примечание 1: Вы получаете составной индекс, имея две аннотации @Index с тем же именем

Примечание 2: Вы указываете имя столбца в списке столбцов, а не имя поля

Ответ 7

OpenJPA позволяет указать нестандартную аннотацию для определения индекса по свойству.

Подробности здесь.

Ответ 8

EclipseLink предоставил аннотацию (например, @Index) для определения индекса в столбцах. Существует example его использования. Часть примера включена...

Поля firstName и lastName индексируются вместе и индивидуально.

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

Ответ 9

Подводя итог другим ответам:

Я бы просто пошел за одним из них. В любом случае он будет иметь JPA 2.1 и не должен быть слишком сложным для изменения в случае, если вы действительно хотите переключить своего поставщика JPA.

Ответ 10

Это невозможно сделать, используя аннотацию JPA. И это имеет смысл: где UniqueConstraint четко определяет бизнес-правила, индекс - это просто способ ускорить поиск. Так что это действительно должно быть сделано администратором баз данных.

Ответ 11

Это решение для EclipseLink 2.5, и оно работает (проверено):

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

Это предполагает восходящий порядок.