使用 Hibernate @Index Annotation 在 DB 上创建索引
Posted
技术标签:
【中文标题】使用 Hibernate @Index Annotation 在 DB 上创建索引【英文标题】:Creating Indexes on DB with Hibernate @Index Annotation 【发布时间】:2011-04-01 18:57:23 【问题描述】:我的项目中有注释驱动的休眠功能。
现在我想在列上创建索引。我当前的列定义是
@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.hbm2ddl.auto=none
,所以在休眠启动时没有失败。我改用 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】:在 Hibernate 3.5.6 中使用 <property name="hibernate.hbm2ddl.auto">update</property
> 创建索引。所以现在一个正确的答案是升级。
但我会把这个答案留给像我这样遇到这个问题的人。
【讨论】:
是的。 hibernate.atlassian.net/browse/HHH-1012 已在 3.2.x、3.3.x、3.5.0-Beta-2 中修复【参考方案3】:在 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的讨论
【讨论】:
只是为了备份这个答案-使用hibernate 4.1.3和mysq更新数据库以创建索引对我有用。如果我向实体添加 @Index 注释,则会自动为我创建索引,而无需删除和重新创建表。【参考方案4】:有趣的是,在我的 Hibernate 配置中,我使用的是 hibernate.hbm2ddl.auto=update
。
这个修改了一个现有的数据库。我手动 DROPping 表 tableName
并重新启动 Tomcat,表已构建但未创建索引。
但是,我创建了 hibernate.hbm2ddl.auto=create
,它会在每次 webapp 实例化时重新创建数据库,它删除了我所有的数据库并重新构建了 - 是的 - 我的新索引已经创建!
【讨论】:
是的,我也注意到了这种行为。全方位 +1。 但是auto.create
设置安全生产吗? ***.com/a/221422/409976如果没有,你如何用hibernate处理索引?
hibernate.atlassian.net/browse/HHH-1012 已修复,现在也可以与 update
一起使用。以上是关于使用 Hibernate @Index Annotation 在 DB 上创建索引的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate5.1.fianl使用JPA注解方式异常:persistence.Table.indexes()[Ljavax/persistence/Index;
为啥使用Hibernate开发web项目的时候在servlet头上使用@webServlet(name="index",urlPatterns="/index&q