【问题标题】:Hibernate 5.1 + Vertica Spatial -- Putting it all togheterHibernate 5.1 + Vertica Spatial -- 将它们放在一起
【发布时间】:2016-08-30 07:41:58
【问题描述】:

错误:

com.vertica.support.exceptions.DataException:[Vertica]VJDBC 错误:无法直接插入或复制用户定义的类型。请使用适当的用户定义函数计算它们

我现在的方言

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 表

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

我的问题:

  • 我应该使用org.geolatte.geom.Polygon 还是别的什么?还有这个com.vividsolutions.jts.geom 包。我很困惑。 Hibernate ORM documentation 没用;它提到了两者,并且示例没有显示导入。
  • 我应该覆盖 Postgis 方言吗? Vertica 使用函数ST_GeographyFromText('LINESTRING(-42.0 23.0, -62.0 23.0)') 加载数据

【问题讨论】:

    标签: hibernate vertica hibernate-spatial


    【解决方案1】:

    您的模型和测试代码都很好。 Hibernate ORM 文档在第 18.1 节解释了为什么有两个几何模型(JTS 和 Geolatte)。你可以选择任何一个。

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

    【讨论】:

    • 感谢您的回复!我正在覆盖 Hibernate Postgis 方言,Vertica 应该具有与 PostGIS 相同的 ST_GeographyFromText(?) 函数:postgis.net/docs/manual-2.2/… .. ?
    • Hibernate Spatial 不是这样工作的。它通过将 java(JTS 或 Geolatte)几何对象直接序列化为二进制本机数据库格式来工作。它不通过任何 st_* 转换函数
    • 好的.. 如果您想向我指出我需要重写的方言函数,我会认为这是一个公认的答案:) 但我自己也会开始查看 api。
    【解决方案2】:

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

    所以是这样的:

    session.createQuery(sql)
        .setParameterList("documentKeys", documentKeys)
        .executeUpdate();
    }
    
     UPDATE tablename  
     SET    wgs84_geo = public.ST_GeographyFromText(wgs84_wkt) 
     WHERE  document_key IN (:documentKeys)
    

    不好的是,在 Vertica 中,更新是新的删除 + 插入,但为了提高查询性能,最好将这些与其余数据放在同一个表中。

    “幸运的是”我们随后发现 Vertica 不支持对多面体的查询,而我们已经拥有,因此我们不得不将几何/地理列从主表中移出,作为链接表,其中每个多边形包含一行多面体。当需要进行地理搜索时,这些链接表会连接到主表以进行查询。事实证明这对我们来说还不够快......但至少我们不再需要在主表上进行插入 + 更新。

    【讨论】:

      猜你喜欢
      • 2017-11-24
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 2016-11-23
      • 2013-06-13
      • 2014-11-17
      • 1970-01-01
      相关资源
      最近更新 更多