8

前の質問に関連しています。Hibernateを使用してGeometryオブジェクトをJTSを使用してPostGISデータベースに書き込むSpringRooアプリケーションがあります。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

私はこの単純なユースケース(単一のGeometryプロパティを持つオブジェクト)を1週間以上機能させようとしてきましたが、もうすぐ終わりです。GeometryオブジェクトをStringに置き換えると、問題なく機能します。誰かがそのようなエラーを引き起こしている可能性があることを知っていますか?

編集:以下のティエリーの答えは私にソースを突っ込んでもらいました、そして私は例外がスローされていることに気づきました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.PostgisDialectHibernateSpatial使用ガイドによるとです。Hibernate Spatial 4.0-M1、JTS 1.12、およびPostGIS2.0.1を使用しています。おそらく、PostGISのいくつかの異なるバージョンを試してみます。特に、Hibernate Spatialが提供するはずの依存関係の1つであるため、そうではないようです。

4

3 に答える 3

14

It seems the problem was that the PostgisDialect was not been picked up and integrated correctly, and hence the required operations were not supported. The solution was as simple as upgrading from Hibernate 3.6.9.Final to 4.1.6.Final!

See my thread on the mailing list for more information.

As per that thread, you should also be aware that as of Hibernate Spatial 4.0-M1, only the Geometry type is specified to Hibernate, and hence the @Column annotation must set columnDefinition="Geometry", and not Point or anything else. This may be fixed in the future.

With this anthology of modifications, I can finally write a Point to a database! The correct property specification is:

@Column(columnDefinition="Geometry")
@Type(type = "org.hibernate.spatial.GeometryType")
private Point centerPoint;
于 2012-09-04T10:04:04.673 に答える
1

はい、?保存する必要がある値に置き換えられます。

GeometryUserTypeではなく、次のタイプを使用しようとしましたGeometryTypeか? GeometryTypeHibernate Spatial Project の API によって直接サポートされていないと思われます。これはおそらく抽象クラスであり、データを注釈でマップするために直接インスタンス化することはできません - 私たちが実験したように、シーンを超えて機能します。

Caused by: java.lang.UnsupportedOperationExceptionそれは私にそれを言わせました。

そして、従ったチュートリアル内の最後の XMLは明らかです。

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

GeometryUserType内のコードを見ると、これらの例外がスローされる可能性のある場所が 1 か所しかありません。

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 Geometry の略であると思います (またはおそらく PostgreSQL)。

Karel Maesen や他の人が InnoDB のサポートについて話しているいくつかのトピックはあまりよくありませんが、それらはおそらく時代遅れです ( 05-2011 )。

幸運を!

于 2012-09-02T14:46:10.370 に答える