Hibernate的坚持与失败PostGIS几何(Hibernate persist failure

2019-06-27 17:11发布

与前一个问题 。 我使用Hibernate写一个几何对象使用JTS一个PostGIS的数据库中有一个Spring Roo的应用。 我相信我已经固定,我在我的定义几何对象的问题,现在的Hibernate执行其persist()方法,但有些事情是会错了,它击中DB之前,我得到下面的异常。

这里有一些有趣的线路。 首先从休眠的日志,则对象被保留,然后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

我一直在努力现在得到了一个多星期的工作这个简单的用例(只是一个单一的几何属性的对象),而我即将在我束手无策。 如果我有一个字符串替换几何对象只是正常工作。 有谁知道什么可能会导致这样的错误?

编辑:亨利的回答下面让我通过源戳,我注意到了异常抛出GeometrySqlTypeDescriptor ,其中有一些有趣的内容:

/**
 * 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.hibernate.spatial.dialect.postgis.PostgisDialect当按照Hibernate的空间使用指南 。 我使用Hibernate的空间4.0-M1,JTS 1.12,和PostGIS的2.0.1。 我会尝试用几个不同版本的PostGIS的可能,特别是因为这是一个依赖的是Hibernate的空间应该提供,但似乎没有。

Answer 1:

看来问题是,PostgisDialect没有被拾起,并正确地整合,因此需要的操作,不支持。 解决的办法是从休眠3.6.9.Final升级到4.1.6.Final简单!

看到我的邮件列表上线以获取更多信息 。

由于每个线程,你也应该知道,作为休眠空间4.0-M1,只有几何类型被指定为休眠,因此@Column注释必须设置columnDefinition="Geometry" ,而不是 Point或其他任何东西。 这可能是固定在将来。

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

@Column(columnDefinition="Geometry")
@Type(type = "org.hibernate.spatial.GeometryType")
private Point centerPoint;


Answer 2:

我得到这个例外,当我忘了加上PostGIS的方言在Hibernate配置文件。

添加下面一行到hibernate.cfg.xml

<property name="dialect">org.hibernate.spatial.dialect.postgis.PostgisDialect</property>


Answer 3:

是的, ? 通过你需要存储的值取代。

你尝试使用以下类型: GeometryUserType而不是GeometryType ? 我怀疑GeometryType不是直接由Hibernate的空间项目的API支持。 这也许是一个抽象类,你不能直接实例化的DATAS与注释地图 - 它的作用超越了现场,因为我们已经尝试。

Caused by: 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的)。

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

祝好运!



文章来源: Hibernate persist failure with PostGIS Geometry