Question

I'm using (spatial) hibernate annotations to create a schema for a spatial application that is implemented on top of PostGIS. When creating the database schema from my annotated classes, I'm in need to create spatial indexes for speeding up spatial queries that are used throughout the application.

@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;
    [...]
}

While the exported schema contains the index, unfortunately it has been created with an undesired index method; hibernate seems to default to btree however PostGIS recommends the use of GIST indexes when dealing with spatial data (see http://postgis.net/docs/manual-2.0/using_postgis_dbmanagement.html#id441511).

CREATE INDEX idx_my_class_sidx
    ON my_class
    USING btree
    (geom);

Whereas I might just fall back creating the index with plain SQL, I'm wondering if there is a way to use hibernate annotations to override the default method type for PostgreSQL? Solutions or even ideas how to do that would be highly appreciated.

TIA, Tilman

Was it helpful?

Solution

I investigated the issue and it seems like Denis is right. From looking at the class Index from the current hibernate implementation (cf. 1), it becomes clear that specification of index types is not supported, yet.

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

The most simple workaround is to call session.createSQLQuery() and to issue CREATE INDEX yourself. This however, is a database-specific operation that needs to be maintained by the applications developer (in case the database is changed).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top