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);
我的问题:
- 我应该使用
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 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.
上进行插入 + 更新
错误:
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);
我的问题:
- 我应该使用
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 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.
上进行插入 + 更新