使用Hibernate Spatial将MultiPolygon几何体保持到PostgreSQL数据库

时间:2015-05-15 19:36:56

标签: jpa hibernate-spatial

我正在学习hibernate空间,我正试图遵循这个tutorial

我试图将MultiPolygon持久保存到Postgres数据库。

我的数据库脚本:

create database multipolygon_test;
create extension postgis;
create extension postgis_topology;
create table test(
    id  bigint
); 
SELECT AddGeometryColumn ('public','test','the_geom',4326,'MULTIPOLYGON',2);

我在项目中使用这些依赖项:

<dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-spatial</artifactId>
        <version>4.3</version>
        <exclusions>
            <exclusion>
                <groupId>postgresql</groupId>
                <artifactId>postgresql</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.postgis</groupId>
                <artifactId>postgis-jdbc</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.7.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.7.Final</version>
    </dependency>

    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901.jdbc4</version>
    </dependency>

    <dependency>
        <groupId>org.postgis</groupId>
        <artifactId>postgis-jdbc</artifactId>
        <version>1.3.3</version>
    </dependency>

我的实体类看起来像这样:

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import com.vividsolutions.jts.geom.MultiPolygon ;

@Entity
@Table(name = "test")
public class Test implements Serializable {
    private static final long serialVersionUID = -8097794061468336996L;

    @Id
    private long id;

    @Column(name = "the_geom", columnDefinition = "org.postgis.MultiPolygon")
    @Type(type = "org.hibernate.spatial.GeometryType")
    private MultiPolygon geometry;

//--- getters & setters ommited

我的持久性xml

<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">
    <persistence-unit
        name="org.hibernate.events.jpa"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>test.Test</class>
        <properties>
            <property
                name="hibernate.dialect"
                value="org.hibernate.spatial.dialect.postgis.PostgisDialect" />

            <property
                name="hibernate.connection.driver_class"
                value="org.postgresql.Driver" />
            <property
                name="hibernate.connection.url"
                value="jdbc:postgresql://localhost:5432:multipolygon_test" />
            <property
                name="hibernate.connection.username"
                value="" />
            <property
                name="hibernate.connection.password"
                value="" />
            <property
                name="hibernate.connection.pool_size"
                value="5" />

            <property
                name="hibernate.show_sql"
                value="true" />
            <property
                name="hibernate.format_sql"
                value="true" />

            <property
                name="hibernate.max_fetch_depth"
                value="5" />

            <property
                name="hibernate.hbm2ddl.auto"
                value="update" />

        </properties>
    </persistence-unit>
</persistence>

JPAUtil类:

public class JPAUtil {

    private static final EntityManagerFactory emFactory;

    static {
        try {
            emFactory = Persistence.createEntityManagerFactory("org.hibernate.events.jpa");
        } catch (Throwable ex) {
            System.err.println("Cannot create EntityManagerFactory.");
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static EntityManager createEntityManager() {
        return emFactory.createEntityManager();
    }

    public static void close() {
        emFactory.close();
    }
}

电话:

public static void main(String[] args) {
        String polygon = "MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))";

        WKTReader fromText = new WKTReader(new GeometryFactory(new PrecisionModel(), 4326));
        Geometry geom = null;
        try {
            geom = fromText.read(polygon);
        } catch (ParseException e) {
            throw new RuntimeException("Not a WKT string:" + polygon);
        }

        EntityManager em = JPAUtil.createEntityManager();

        em.getTransaction().begin();

        Test test = new Test();
        test.setId(1);
        test.setGeometry(((com.vividsolutions.jts.geom.MultiPolygon) geom));
        em.persist(test);
        em.getTransaction().commit();
        em.close();

        JPAUtil.close();

    }

例外:

Caused by: org.postgresql.util.PSQLException: Unknown type geometry.
    at org.postgresql.jdbc2.AbstractJdbc2Statement.setPGobject(AbstractJdbc2Statement.java:1603)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:1795)
    at org.postgresql.jdbc3g.AbstractJdbc3gStatement.setObject(AbstractJdbc3gStatement.java:37)
    at org.postgresql.jdbc4.AbstractJdbc4Statement.setObject(AbstractJdbc4Statement.java:46)
    at org.hibernate.spatial.dialect.AbstractJTSGeometryValueBinder.bind(AbstractJTSGeometryValueBinder.java:48)
    at org.hibernate.spatial.dialect.AbstractJTSGeometryValueBinder.bind(AbstractJTSGeometryValueBinder.java:39)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:286)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:281)
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:56)
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2843)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3121)
    ... 12 more

我不知道可能出现什么问题。我尝试用com.vividsolutions.jts.geom.Geometry,org.postgis.Geometry,org.postgis.MuliPolygon替换MultiPolygon,尝试将columnDefiniton指定为&#34; Geometry(multipolygon,4326)&# 34;但无济于事。

我唯一能想到的是我的依赖关系被搞砸了,但我也尝试过将hibernate-spatial 4.0.1与hibernate 4.2.0一起使用。这没有帮助。

1 个答案:

答案 0 :(得分:0)

我发现了这个问题。如果您的问题仍然存在,请尝试更改:

        <property
            name="hibernate.connection.driver_class"
            value="org.postgresql.Driver" />

成:

        <property
            name="hibernate.connection.driver_class"
            value="org.postgis.DriverWrapper" />

因为您实际上使用的是PostgreSql驱动程序,而没有添加Spatial功能。 Postgis Driver Wrapper正在为您添加它们。