Creating Indexes on DB with Hibernate @Index Annotation

a 夏天 提交于 2019-11-30 08:14:32

Interestingly, in my Hibernate configuration I was using hibernate.hbm2ddl.auto=update.

This one modifies an existing database. I was manually DROPping the table tableName and restarting Tomcat and the table had been constructed but index was not being created.

However, I made hibernate.hbm2ddl.auto=create which re-creates database upon each instantiation of webapp, it dropped all my database and rebuilt back and -hell yeah- my new index has been created!

Index creation on schema update was intentionally disabled in Hibernate because it seemed inconsistent with the naming used in the schema export.

This is the commented code that you can find in class 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) );
    }
}

Usually I remove that comment, recompile Hibernate.jar and have indexes created on schema update without any problem, at least with Oracle DB.

In recent versions of Hibernate the comment on the first part (table indexes) has been removed in the official version as well, while it's still commented the second one (indexes that implement unique keys). See the discussion at http://opensource.atlassian.com/projects/hibernate/browse/HHH-1012

Better DB design means the schema is owned by a different user than the data itself. Hence I set hibernate.hbm2ddl.auto=none so there are no failures upon Hibernate start. I use a SchemaPrinter instead. The output of which can be run via my favorite SQL tool to recreate the schema when required.

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);
    }

}

In Hibernate 3.5.6 using <property name="hibernate.hbm2ddl.auto">update</property> the indexes are created. So a proper answer now would be to upgrade. But I'm leaving this answer for those like me that have come across this question.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!