Создание индексов в БД с помощью Hibernate @Index Annotation
У меня есть управляемые аннотациями возможности спящего режима в моем проекте.
Теперь я хочу создать индекс над столбцом. Мое текущее определение столбца
@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.
Ответы
Ответ 1
Интересно, что в моей конфигурации Hibernate я использовал hibernate.hbm2ddl.auto=update
.
Этот изменяет существующую базу данных. Я вручную удалил таблицу tableName
и перезапустил Tomcat, и таблица была построена, но индекс не создавался.
Однако я сделал hibernate.hbm2ddl.auto=create
, который повторно создает базу данных при каждом экземпляре webapp, он отбросил всю мою базу данных и перестроил обратно, и -hell да, мой новый индекс был создан!
Ответ 2
Создание индекса в обновлении схемы было намеренно отключено в 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
Ответ 3
Лучшая конструкция БД означает, что схема принадлежит другому пользователю, чем сама информация. Следовательно, я устанавливаю 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);
}
}
Ответ 4
В Hibernate 3.5.6 с использованием <property name="hibernate.hbm2ddl.auto">update</property
> создаются индексы. Поэтому правильный ответ теперь должен был обновиться.
Но я оставляю этот ответ для таких, как я, которые столкнулись с этим вопросом.