Hibernate 5.1 + Vertica Spatial——将它们放在一起

Hibernate 5.1 + Vertica Spatial -- Putting it all togheter

错误:

com.vertica.support.exceptions.DataException: [Vertica]VJDBC ERROR: Cannot INSERT or COPY user-defined types directly. Please compute them using appropriate user-defined functions

我现在的方言

public class VerticaDialect extends org.hibernate.spatial.dialect.postgis.PostgisDialect {

private static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()";

@Override
public IdentityColumnSupport getIdentityColumnSupport() {

    return new IdentityColumnSupport() {
        ...
        @Override
        public String getIdentitySelectString(String arg0, String arg1, int arg2) throws MappingException {
            return SELECT_LAST_INSERT_ID;
        }
        ...
    };
}

}

我的依赖

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.1.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.1.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-spatial</artifactId>
     <version>5.1.1.Final</version>
</dependency>
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0</version>
</dependency>

我的 Vertica table

alter table something add GIS_WGS84 GEOGRAPHY NULL;

我的模型

import org.geolatte.geom.C2D;
import org.geolatte.geom.G2D;
import org.geolatte.geom.Polygon;

@Column(name="gis_wgs84")
public Polygon<G2D> getGisWGS84() {
    return gisWGS84;
}

public void setGisWGS84(Polygon<G2D> gisWGS84) {
    this.gisWGS84 = gisWGS84;
}

我的测试

Geographic2DCoordinateReferenceSystem wgs84 = CrsRegistry.getGeographicCoordinateReferenceSystemForEPSG(4326); // G2D

PositionSequence<G2D> wgs84positionSequence = 
                PositionSequenceBuilders.fixedSized(5, G2D.class)
                .add(new G2D(30.0, 60.0))
                .add(new G2D(30.0, 61.0))
                .add(new G2D(31.0, 61.0))
                .add(new G2D(31.0, 60.0))
                .add(new G2D(30.0, 60.0))
                .toPositionSequence();
Polygon<G2D> wgs84poly = new Polygon<>(wgs84positionSequence, wgs84);
something.setGisWGS84(wgs84poly);

我的问题:

你的模型和测试代码没问题。 Hibernate ORM 文档解释了为什么在第 18.1 节中有两个几何模型(JTS 和 Geolatte)。任选其一。

问题出在您的 Vertica 方言上。实施 Vertica 空间方言还有更多内容。 Hibernate Spatial 需要将 Java 空间对象序列化为特定于数据库的格式。但是,Hibernate Spatial 目前不知道如何为 Vertica 数据库执行此操作。

覆盖方言将是一项艰巨的任务,因此我们决定将几何数据加载为 WKT,然后在将所有行插入到 Vertica 后调用对插入行的新更新,填充 Geometry/Geography 列。

所以像这样:

session.createQuery(sql)
    .setParameterList("documentKeys", documentKeys)
    .executeUpdate();
}

 UPDATE tablename  
 SET    wgs84_geo = public.ST_GeographyFromText(wgs84_wkt) 
 WHERE  document_key IN (:documentKeys)

糟糕的是,在 Vertica 中,更新是新的删除 + 插入,但为了查询性能,最好将它们与其余数据放在同一 table 中。

"Luckily" 然后我们发现 Vertica 不支持我们支持的多面体查询,因此我们不得不将 Geometry/Geography 列从链接的主要 table 中移开table 包含多面体中每个多边形的一行。这些链接的 table 与主 table 相连,以便在需要地理搜索时进行查询。事实证明这对我们来说还不够快......但至少我们不再需要在主 table.

上进行插入 + 更新