18

У меня есть управляемые аннотациями hibernate capabilies в моем проекте.Создание индексов на БД с Hibernate @Index Аннотация

Теперь я хочу создать индекс над столбцом. Мое текущее определение столбца

@NotNull 
@Column(name = "hash") 
private String hash; 

и добавить @Index аннотацию здесь.

@NotNull 
@Column(name = "hash") 
@Index(name="hashIndex") 
private String hash; 

, а затем DROP TABLE и перезапустить сервер Tomcat. После создания экземпляра сервера создается таблица, но я не вижу новый индекс для следующего запроса.

SHOW INDEX FROM tableName 

Ожидается, что будет построен стол с новым индексом. Я использую InnoDB с MySQL.

ответ

16

Интересно, что в моей конфигурации Hibernate я использовал hibernate.hbm2ddl.auto=update.

Эта модификация изменяет существующую базу данных. Я вручную удалил таблицу tableName и перезапустил Tomcat, и таблица была построена, но индекс не создавался.

Тем не менее, я сделал hibernate.hbm2ddl.auto=create, который заново создает базу данных при каждом экземпляре webapp, он отбросил всю мою базу данных и перестроил обратно, и -hell да, мой новый индекс был создан!

+0

Да, я также заметил это поведение. +1 вокруг. –

+0

Но является ли это 'auto.create' настройка безопасной для производства? http://stackoverflow.com/a/221422/409976, если нет, как вы обрабатываете индексы с гибернацией? –

+1

https://hibernate.atlassian.net/browse/HHH-1012 исправлено, теперь работает также с 'update'. – gavenkoa

9

Создание индекса в обновлении схемы было намеренно отключено в Hibernate, поскольку оно казалось несовместимым с именованием, используемым при экспорте схемы.

Это комментируемый код, который вы можете найти в классе org.hibernate.cfg.Configuration.

//broken, 'cos we don't generate these with names in SchemaExport 
subIter = table.getIndexIterator(); 
while (subIter.hasNext()) { 
    Index index = (Index) subIter.next(); 
    if (!index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey()) { 
     if (tableInfo==null || tableInfo.getIndexMetadata(index.getFilterName()) == null) { 
      script.add(index.sqlCreateString(dialect, mapping)); 
     } 
    } 
} 
//broken, 'cos we don't generate these with names in SchemaExport 
subIter = table.getUniqueKeyIterator(); 
while (subIter.hasNext()) { 
    UniqueKey uk = (UniqueKey) subIter.next(); 
    if (tableInfo==null || tableInfo.getIndexMetadata(uk.getFilterName()) == null) { 
     script.add(uk.sqlCreateString(dialect, mapping)); 
    } 
} 

Обычно я удалить этот комментарий, перекомпилировать Hibernate.jar и имеют индексы, созданные при обновлении схемы без каких-либо проблем, по крайней мере, с БД Oracle.

В последних версиях Hibernate комментарий в первой части (индексы таблицы) также был удален в официальной версии, в то время как он по-прежнему комментирует второй (индексы, которые реализуют уникальные ключи). См. Обсуждение на http://opensource.atlassian.com/projects/hibernate/browse/HHH-1012

+2

просто для резервного копирования этого ответа - обновление базы данных для создания индексов работает для меня с использованием hibernate 4.1.3 и mysq. Индексы создаются для меня автоматически, не отбрасывая и воссоздавая таблицы, если я добавляю аннотацию @Index к сущности. – jportway

2

В Hibernate 3.5.6 с использованием <property name="hibernate.hbm2ddl.auto">update</property> индексы создаются. Поэтому правильный ответ теперь должен был обновиться. Но я оставляю этот ответ для таких, как я, которые столкнулись с этим вопросом.

+0

Да. https://hibernate.atlassian.net/browse/HHH-1012 исправлено в 3.2.x, 3.3.x, 3.5.0-Beta-2 – gavenkoa

4

Лучшая конструкция БД означает, что схема принадлежит другому пользователю, чем данные. Следовательно, я устанавливаю hibernate.hbm2ddl.auto=none, поэтому никаких сбоев при запуске Hibernate нет. Вместо этого я использую SchemaPrinter. Выход из которого можно запустить с помощью моего любимого инструмента SQL, чтобы воссоздать схему, когда это необходимо.

import java.io.IOException; 

import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.cfg.Environment; 
import org.hibernate.tool.hbm2ddl.SchemaExport; 

public class SchemaPrinter { 

    public static void main(String[] args) throws IOException { 

     Configuration cfg = new AnnotationConfiguration() 
      .addAnnotatedClass(MyClass1.class) 
      .addAnnotatedClass(MyClass2.class) 
      .setProperty(Environment.USER, "user") 
      .setProperty(Environment.PASS, "password") 
      .setProperty(Environment.URL, "jdbc:sybase:jndi:file://sql.ini?mydb") 
      .setProperty(Environment.DIALECT, "org.hibernate.dialect.SybaseASE15Dialect") 
      .setProperty(Environment.DRIVER, "com.sybase.jdbc4.jdbc.SybDriver") 
      .setProperty(Environment.HBM2DDL_AUTO, "none") 
     SchemaExport exp = new SchemaExport(cfg); 
     exp.setOutputFile("schema.ddl"); 
     exp.create(true, false); 
    } 

} 
Смежные вопросы