Java 使用 Hibernate @Index Annotation 在 DB 上创建索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3533301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:38:02  来源:igfitidea点击:

Creating Indexes on DB with Hibernate @Index Annotation

javahibernateannotationshibernate-annotationsdatabase-indexes

提问by AhmetB - Google

I have annotation-driven hibernate capabilies on my project.

我的项目中有注释驱动的休眠功能。

Now I want to create an index over a column. My current column definition is

现在我想在一列上创建一个索引。我当前的列定义是

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

and I add @Indexannotation here.

我在@Index这里添加注释。

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

and then DROP TABLE and restart Tomcat server. After the server is instantiated, the table is created but I can't see new index on following query.

然后删除表并重新启动Tomcat服务器。服务器实例化后,表已创建,但在以下查询中看不到新索引。

SHOW INDEX FROM tableName

It is expected to construct table with new index. I am using InnoDB with MySQL.

预计用新索引构造表。我在 MySQL 中使用 InnoDB。

采纳答案by AhmetB - Google

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

有趣的是,在我的 Hibernate 配置中,我使用了hibernate.hbm2ddl.auto=update.

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

这个修改了一个现有的数据库。我正在手动删除表tableName并重新启动 Tomcat,并且表已构建但未创建索引。

However, I made hibernate.hbm2ddl.auto=createwhich 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!

但是,我hibernate.hbm2ddl.auto=create在每次 webapp 实例化时都重新创建了数据库,它删除了我所有的数据库并重建了 - 地狱是的 - 我的新索引已经创建!

回答by Stefano Travelli

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

在 Hibernate 中故意禁用模式更新时的索引创建,因为它似乎与模式导出中使用的命名不一致。

This is the commented code that you can find in class org.hibernate.cfg.Configuration.

这是您可以在 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.

通常我会删除该注释,重新编译 Hibernate.jar 并在模式更新时创建索引,没有任何问题,至少对于 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

在最新版本的 Hibernate 中,第一部分(表索引)的注释在正式版本中也被删除了,而第二部分(实现唯一键的索引)仍然被注释。请参阅http://opensource.atlassian.com/projects/hibernate/browse/HHH-1012 上的讨论

回答by Paulo Fidalgo

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.

在 Hibernate 3.5.6 中使用<property name="hibernate.hbm2ddl.auto">update</property> 创建索引。所以现在正确的答案是升级。但是我将这个答案留给像我这样遇到过这个问题的人。

回答by gabor

Better DB design means the schema is owned by a different user than the data itself. Hence I set hibernate.hbm2ddl.auto=noneso 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.

更好的数据库设计意味着架构由与数据本身不同的用户拥有。因此我设置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);
    }

}