Создание индексов в БД с помощью Hibernate @Index Annotation - PullRequest
18 голосов
/ 20 августа 2010

В моем проекте есть возможности гибернации на основе аннотаций.

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

@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.

Ответы [ 4 ]

17 голосов
/ 20 августа 2010

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

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

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

9 голосов
/ 01 марта 2011

Создание индекса при обновлении схемы было преднамеренно отключено в 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 DB.

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

4 голосов
/ 12 декабря 2013

Лучший дизайн БД означает, что схема принадлежит другому пользователю, нежели сами данные. Поэтому я установил 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);
    }

}
2 голосов
/ 06 ноября 2013

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

...