Как использовать аннотации Hibernate для добавления индекса в Lob / Clob / tinyblob - PullRequest
4 голосов
/ 13 мая 2009

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

У меня проблема в том, что индексы в моем поле byte [] не созданы; в частности, что многопольный индекс sysUuid не создается (см. пример кода). В журналах отладки Hibernate я даже не вижу попытки создать индекс!

Я хотел бы отметить, что аннотация @Index в поле uuid также не приводит к индексу в базе данных.

Я знаю, как создать индекс вручную, используя MySQL:

create index sysuuid on persons ( system, `uuid`(8) );

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

Однако я не нашел способа задать поле длины индекса с помощью аннотаций Hibernate, поэтому я не могу проверить, является ли это проблемой. Однако очевидно, что присвоение имени полю «uuid (8)» в аннотации не работает.

@Entity
// The UniqueConstraints work 
@Table(name = "persons", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"uid", "system"}) } )
// but these don't generate an index
@org.hibernate.annotations.Table(appliesTo="persons", 
   indexes={@Index(name="sysUuid",  columnNames={"system", "uuid"})  } )
public class Person  {
    @Basic 
    @NotNull
    private String uid;

    @Basic
    private int system;

    // Gets mapped to tinyblob
    @Basic
    @Size(min = 16, max = 16)
    private byte[] uuid;

    // getters and setters here 
}

Я хотел бы спросить вас: возможно ли добавить индекс на лепесток, используя аннотацию, и если да, то как?

EDIT

Для меня действительно возможно перейти к строковому UUID, но я не очень доволен этим, поскольку концептуально uuid является 16-байтовым идентификатором.

Я настоятельно предпочитаю, чтобы типы Java соответствовали проблемной области.

И, как я уже сказал, у меня есть удобный оператор SQL, поэтому я могу развернуть код + сценарий SQL. Я просто думаю, что лучше иметь самодокументируемый код, когда это возможно.

РЕДАКТИРОВАТЬ & Добавленная награда

Я считаю, что нужный мне индекс не может быть создан с использованием аннотаций Hibernate (см. Ответ Мэтта Солнита).

Однако я был бы признателен за дополнительную информацию о создании индексов с аннотациями Hibernate в целом, так что окончательный ответ заканчивается документированием ограничений API.

Ответы [ 3 ]

3 голосов
/ 14 мая 2009

Вы можете сделать это, используя вспомогательные объекты Hibernate , но это невозможно сделать с помощью аннотаций: - (.

В вашем примере это выглядело бы примерно так (многие вещи опущены для краткости):

<class name="Person" table="persons">
  <!-- whatever -->
  <database-object>
    <create>create index sysuuid on persons ( system, `uuid`(8) )</create>
    <drop>drop index sysuuid</drop>
    <dialect-scope name="org.hibernate.dialect.MySQL5InnoDBDialect" />
  </database-object>
</class>

Прошу прощения за отсутствие ответа на основе аннотации :-(. Надеюсь, это поможет.

ПРИМЕЧАНИЕ : Если вы используете этот подход, помните, что область диалекта должна точно соответствовать . Например, если ваша конфигурация Hibernate говорит использовать MySQL5InnoDBDialect, то этот диалект должен быть и в элементе <dialect-scope>. Использование MySQLDialect не будет работать, даже если это суперкласс диалекта InnoDB.

1 голос
/ 13 мая 2009

Что вы действительно хотите сделать, так это определить свойство UUID в виде строки, а не байтового массива. Таким образом, Hibernate сопоставит его с символьным столбцом в базе данных, а не с LOB, и я думаю, что он создаст нужный вам индекс.

0 голосов
/ 23 декабря 2012

Вот мои результаты исследований с MySQL. Если у вас есть поле большой длины:

@Column(length = 2000)
public String getMessageId() {
    return messageId;
}

тогда его тип будет BLOB и индексирование не будет работать:

HHH000389: Unsuccessful: create index messageid_idx on MessageDetails (messageId)
BLOB/TEXT column 'messageId' used in key specification without a key length      

Если вы используете аннотации, единственный способ добавить пользовательский sql - это:

    cfg.addAuxiliaryDatabaseObject(new SimpleAuxiliaryDatabaseObject(
            "CREATE INDEX messageId_IDX ON MessageDetails(MessageID(128))",
            "DROP INDEX messageId_IDX ON MessageDetails"));

где cfg - объект, который используется для регистрации аннотаций:

    cfg.addAnnotatedClass(MessageDetails.class);

это работает для меня. Спасибо за ваше внимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...