当前位置: 首页 > 知识库问答 >
问题:

Hibernate使用PostGIS几何体持续失败

程胤运
2023-03-14

与上一个问题有关。我有一个SpringRoo应用程序,它使用Hibernate使用JTS将几何体对象写入PostGIS数据库。我相信我已经解决了定义Geometry对象时遇到的问题,现在Hibernate正在执行其persist()方法,但是在它到达DB之前出现了一些问题,我得到了下面的异常。

这里有一些有趣的台词。首先从Hibernate日志、要持久化的对象,然后是一个SQL查询(可能替换了?):

...
DEBUG org.hibernate.pretty.Printer - com.test.LandUse{id=1, centerPoint=POINT (5 6), version=0}
...
DEBUG org.hibernate.SQL - insert into land_use (center_point, version, id) values (?, ?, ?)
...

然后发生了更多的事情,尽管没有明显的坏事。然而,我没有看到任何“最终”SQL,并且有人试图回滚事务。然后:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$afterReturning$org_springframework_transaction_aspectj_AbstractTransactionAspect$3$2a73e96c(AbstractTransactionAspect.aj:78)
    at com.test.LandUse_Roo_Jpa_ActiveRecord.ajc$interMethod$com_test_LandUse_Roo_Jpa_ActiveRecord$com_test_LandUse$persist(LandUse_Roo_Jpa_ActiveRecord.aj:44)
    at com.test.LandUse.persist(LandUse.java:1)
    at com.test.LandUse_Roo_Jpa_ActiveRecord.ajc$interMethodDispatch1$com_test_LandUse_Roo_Jpa_ActiveRecord$com_test_LandUse$persist(LandUse_Roo_Jpa_ActiveRecord.aj)
    at com.test.LandUseController_Roo_Controller.ajc$interMethod$com_test_LandUseController_Roo_Controller$com_test_LandUseController$create(LandUseController_Roo_Controller.aj:29)
    at com.test.LandUseController.create(LandUseController.java:1)
...
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:93)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512)
    ... 54 more
Caused by: java.lang.UnsupportedOperationException
    at org.hibernate.spatial.GeometrySqlTypeDescriptor.getBinder(GeometrySqlTypeDescriptor.java:52)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:283)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:278)
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:89)
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2184)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2430)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2874)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
    ... 55 more

我已经试着让这个简单的用例(一个只有一个几何体属性的对象)工作了一个多星期了,现在我已经不知所措了。如果我用字符串替换几何体对象,它就可以正常工作。有人知道是什么导致了这样的错误吗?

编辑:Thierry下面的回答让我浏览了源代码,我注意到异常抛出在GeometrySqlTypeExplptor中,其中有一些有趣的内容:

/**
 * A generic <code>SqlTypeDescriptor</code>, intended to be remapped
 * by the spatial dialect.
 *
 * @author Karel Maesen, Geovise BVBA
 *         creation-date: 7/27/11
 */
public class GeometrySqlTypeDescriptor implements SqlTypeDescriptor {

    public static final GeometrySqlTypeDescriptor INSTANCE = new GeometrySqlTypeDescriptor();

    @Override
    public int getSqlType() {
        return 3000; //this value doesn't conflict with presently defined java.sql.Types values.
    }

    @Override
    public boolean canBeRemapped() {
        return true;
    }

    @Override
    public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
        throw new UnsupportedOperationException();
    }

    @Override
    public <X> ValueExtractor<X> getExtractor(JavaTypeDescriptor<X> javaTypeDescriptor) {
        throw new UnsupportedOperationException();
    }
}

特别要注意的是,类注释表明Hibernate方言映射显然有问题。不幸的是,我不知道这意味着什么,但我猜是由于某种版本不匹配。(另请注意SQL类型3000的声明,与我之前的错误相同!)

我现在的方言是org。冬眠空间的地方话波斯特吉斯。PostGis方言,根据Hibernate空间使用指南。我正在使用HibernateSpatial 4.0-M1、JTS1.12和PostGIS 2.0。1.我可能会尝试使用几个不同版本的PostGIS,特别是因为Hibernate Spatial应该提供但似乎没有提供这种依赖关系。

共有3个答案

程俊力
2023-03-14

是的,代码?被需要存储的值取代。

您是否尝试使用以下类型:GeometryUserType而不是GeometryType?我怀疑Hibernate Spatial项目的API不直接支持GeometryType。它可能是一个抽象类,您无法直接实例化它来映射带有注释的数据-它的行为超出了我们的实验场景。

原因:java。lang.UnsupportedOperationException这让我不得不这么说。

您遵循的教程中的最后一个XML内容很清楚:

...
<property name="geometry" type="org.hibernatespatial.GeometryUserType">
    <column name="geom" />
</property>
...

查看GeometryUserType中的代码,我只看到一个可以抛出这些异常的地方。

public Object conv2DBGeometry(Geometry jtsGeom, Connection connection) {
        org.postgis.Geometry geom = null;
        jtsGeom = forceEmptyToGeometryCollection(jtsGeom);
        if (jtsGeom instanceof com.vividsolutions.jts.geom.Point) {
            geom = convertJTSPoint((com.vividsolutions.jts.geom.Point) jtsGeom);
        } else if (jtsGeom instanceof com.vividsolutions.jts.geom.LineString) {
            geom = convertJTSLineString((com.vividsolutions.jts.geom.LineString) jtsGeom);
        } else if (jtsGeom instanceof com.vividsolutions.jts.geom.MultiLineString) {
            geom = convertJTSMultiLineString((com.vividsolutions.jts.geom.MultiLineString) jtsGeom);
        } else if (jtsGeom instanceof com.vividsolutions.jts.geom.Polygon) {
            geom = convertJTSPolygon((com.vividsolutions.jts.geom.Polygon) jtsGeom);
        } else if (jtsGeom instanceof com.vividsolutions.jts.geom.MultiPoint) {
            geom = convertJTSMultiPoint((com.vividsolutions.jts.geom.MultiPoint) jtsGeom);
        } else if (jtsGeom instanceof com.vividsolutions.jts.geom.MultiPolygon) {
            geom = convertJTSMultiPolygon((com.vividsolutions.jts.geom.MultiPolygon) jtsGeom);
        } else if (jtsGeom instanceof com.vividsolutions.jts.geom.GeometryCollection) {
            geom = convertJTSGeometryCollection((com.vividsolutions.jts.geom.GeometryCollection) jtsGeom);
        }

        if (geom != null)
            return new PGgeometry(geom);
        else
            throw new UnsupportedOperationException("Conversion of "
                    + jtsGeom.getClass().getSimpleName()
                    + " to PGgeometry not supported");
    }

我认为PGgeometry代表PostGis几何(或者PostgreSQL)。

我发现卡雷尔·梅森和其他人谈论InnoDB支持的一些话题不是很好,但它们可能已经过时了(05-2011)。

祝你好运

皮安顺
2023-03-14

当我忘记在Hibernate配置文件中添加Postgis方言时,我得到了这个异常

添加以下行到hibernate.cfg.xml

<property name="dialect">org.hibernate.spatial.dialect.postgis.PostgisDialect</property>
子车宏浚
2023-03-14

问题似乎是PostgisDialect没有被正确地拾取和集成,因此不支持所需的操作。解决方案就像从Hibernate 3.6.9升级一样简单。最终到4.1.6。最终!

有关更多信息,请参阅邮件列表上的我的帖子。

根据该线程,您还应该意识到,在Hibernate Sspace al 4.0-M1中,只有Geometry类型被指定给Hibernate,因此@Col一身注释必须设置柱状定义="Geometry",而不是Point或者其他什么。这在未来可能会得到解决。

有了这本修改集,我终于可以把一个点写到数据库了!正确的属性规范是:

@Column(columnDefinition="Geometry")
@Type(type = "org.hibernate.spatial.GeometryType")
private Point centerPoint;
 类似资料:
  • 问题内容: 与上一个问题有关。我有一个使用Hibernate的Spring Roo应用程序,它使用JTS将Geometry对象写入PostGIS数据库。我相信我已经解决了定义我的Geometry对象时遇到的问题,现在Hibernate正在执行其persist()方法,但是在它到达数据库之前就出了问题,并且在下面出现了异常。 这是一些有趣的行。首先从Hibernate日志中,要持久化的对象,然后是一

  • hibernate 5.1 spatial的文档尚未发布(AFAIK),我正在尝试将带有JST几何字段的实体持久化到PostgreSQL 9.5 Postgis 2.2,但没有任何运气。 我也注意到没有组织。冬眠hibernate-core-5.1中的空间包。0.我尝试了以下注释的变体: 当列定义设置为“点”时,我得到“列”the_geom“是点的类型,但表达式是由茶的类型”。在Hibernate

  • 数据源是具有PostGIS几何类型的PostgreSQL数据库。我可以使用包直接从SQL查询我想要的数据到data.frame。 由于 R 抱怨原始几何类型,因此我在 SQL 查询中对几何使用 以便将它们作为类型存储在 中。我有三种类型:、和。请注意,我的数据是几何(例如,笛卡尔x,y,z坐标),而不是地图投影的地理。 制作MWE有点困难,因为我必须用换行符分隔每个LINESTRING和POLYG

  • POSTGIS=“2.5.4” [扩展] PGSQL=“120” GEOS=“3.8.1-CAPI-1.13.3” PROJ=“Rel. 6.3.2, May 1st, 2020” GDAL=“GDAL 3.0.4, 2020/01/28 发布” LIBXML=“2.9.7” LIBJSON=“0.13.1” LIBPROTOBUF=“1.3.0” RASTER Java Postgis Depe

  • 我想返回此SQL Postgis查询的输出(几何类型中的输出为“0101000000000000000002440000000000002440”) 用Java和hibernate。 我尝试了以下方法: 这对我不起作用。我得到以下异常 我想我明白问题是什么。我尝试将结果解析为字符串,但它是几何对象。但是我该怎么做才能在 Java 中将此输出作为字符串获取?如果我只在 SQL 查询后面添加 .lis

  • 我正在尝试使用postgis设置一个带有hibernate空间的项目。按照hibernate空间4.0-M1的教程,我首先遇到了无法找到依赖postgis-jdbc-1.5.3.jar的问题。就像有人在这里建议的那样,我使用了1.5.2版和教程编译。 但是如果我尝试运行它,我会出错。我将Hibernate的调试级别设置为调试und时偶然发现了以下问题: 错误是德语,但意味着“几何”类型不存在。 如