使用@Index注释时指定索引方法

时间:2013-05-29 07:36:22

标签: hibernate postgresql postgis hibernate-annotations hibernate-spatial

我正在使用(空间)休眠注释来创建在PostGIS之上实现的空间应用程序的模式。从我的带注释的类创建数据库模式时,我需要创建空间索引来加速整个应用程序中使用的空间查询。

@Entity
@Table(name = "MY_CLASS")
@org.hibernate.annotations.Table(
    appliesTo = "MY_CLASS", indexes = {
        @Index(name = "idx_my_class_sidx",
            columnNames = { "GEOM" }) })
public class MyClass {
    [...]
    @Column(name = "GEOM")
    @Type(type = "org.hibernate.spatial.GeometryType")
    private LineString geom;
    [...]
}

虽然导出的模式包含索引,但遗憾的是它是使用不需要的索引方法创建的; hibernate似乎默认为btree,但PostGIS建议在处理空间数据时使用GIST索引(参见http://postgis.net/docs/manual-2.0/using_postgis_dbmanagement.html#id441511)。

CREATE INDEX idx_my_class_sidx
    ON my_class
    USING btree
    (geom);

虽然我可能会退回使用纯SQL创建索引,但我想知道是否有办法使用hibernate注释来覆盖PostgreSQL的默认方法类型?解决方案甚至想法如何做到这一点将受到高度赞赏。

TIA, 蒂尔曼

1 个答案:

答案 0 :(得分:0)

我调查了这个问题,看起来丹尼斯是对的。从当前的hibernate实现(参见1)查看类Index,很明显,不支持索引类型的规范。

public static String buildSqlCreateIndexString(
        Dialect dialect,
        String name,
        Table table,
        Iterator<Column> columns,
        java.util.Map<Column, String> columnOrderMap,
        boolean unique,
        String defaultCatalog,
        String defaultSchema
) {
    StringBuilder buf = new StringBuilder( "create" )
            .append( unique ?
                    " unique" :
                    "" )
            .append( " index " )
            .append( dialect.qualifyIndexName() ?
                    name :
                    StringHelper.unqualify( name ) )
            .append( " on " )
            .append( table.getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
            .append( " (" );
    while ( columns.hasNext() ) {
        Column column = columns.next();
        buf.append( column.getQuotedName( dialect ) );
        if ( columnOrderMap.containsKey( column ) ) {
            buf.append( " " ).append( columnOrderMap.get( column ) );
        }
        if ( columns.hasNext() ) buf.append( ", " );
    }
    buf.append( ")" );
    return buf.toString();
}

最简单的解决方法是致电session.createSQLQuery()并自行发布CREATE INDEX。但是,这是一个特定于数据库的操作,需要由应用程序开发人员维护(如果数据库已更改)。