在PostgreSQL和JPA / Hibernate中使用Point类型

时间:2014-03-05 01:07:33

标签: java hibernate postgresql jpa

有没有办法将Point列映射到Java实体字段?

我尝试了Hibernate Spatial 4.0,但似乎它不适用于没有PostGIS的纯PostgreSQL。这是点数字段定义:

import com.vividsolutions.jts.geom.Point;
...
@Column(columnDefinition = "point")
@Type(type = "org.hibernate.spatial.GeometryType")
private Point location;

persistence.xml中的方言:

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

当我尝试持久保存此实体时,抛出异常:

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:280)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)

似乎它试图将值保持为PostGIS的Geometry类型。但我想使用简单的Point。

5 个答案:

答案 0 :(得分:7)

我可以通过@Embedded Entity(它不依赖于数据库类型!)提供更通用的方法,我已经在项目中使用了它。

以下示例:

使用LAT和LONG创建一些表的SQL查询:

CREATE TABLE some_table (
  lat    NUMBER(..., ...),
  long   NUMBER(..., ...),
...
);

Embeddable Point实体:

@Embeddable
public class Point {
    private BigDecimal x;
    private BigDecimal y;
 ...
}

您的自定义实体:

@Entity
@Table(name = "some_table")
public class SomeEntity {
    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name = "lat", column = @Column(name = "x")),
            @AttributeOverride(name = "long", column = @Column(name = "y"))
    })
    private Point point;
...
}

答案 1 :(得分:6)

在您的数据库中安装POSTGIS EXTENSION。

您遇到的错误是因为您没有在数据库上安装任何与Hibernate相关的内容。正在抱怨的是postgres,即:

  

org.postgresql.util.PSQLException:未知的类型几何。

您的注释和配置表明它们依赖于PostGIS:

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

所以基本上你试图使用不受支持的配置。

PostgreSQL并没有提供所有可能的数据类型,就像Oracle所做的那样。因此,当Hibernate说&#34;我想要一个几何形状&#39; PostgreSQL只是说&#34;什么是几何?&#34; PostgreSQL是非常可扩展的,因此PostGIS人员所做的就是 - 他们构建了一个扩展。任何人都可以安装它或没有它完全运行。它引起的唯一问题是有人在开箱即用的数据库中预期它而不是它是一个附加组件。

我想您可能会尝试对PostgreSQL数据类型进行反向工程并在数据库中进行编译。 Geometry是PostGIS的主要超类,至少在Java中,它在数据库中看起来是一样的。我不知道为什么在你赢得任何人支持它的时候你会设置一个配置。

@bluish有帮助吗?

答案 2 :(得分:5)

您应该尝试将数据库中的类型作为Geometry,我也没有设法使用mySQL。 几何对于点来说效果很好..

答案 3 :(得分:5)

由于我不完全确定这个问题,让我先试试释义:

您希望使用hibernate将具有类型com.vividsolutions.jts.geom.Point字段的实体映射到类型为“point”的PostgreSQL数据库列(参见postgreSQL geometric types),将自己限制为“标准”(即方言PostgreSQLDialect

一些研究使我得出结论,上面提到的hibernate支持的标准方言根本不支持PostgreSQL点类型。因此,您可能希望提供自己的UserType。从hibernate手册或Custom types查看Understanding and writing Hibernate custom user types以获取博客中的示例。

答案 4 :(得分:0)

此链接将为您提供帮助 LINK https://www.compose.com/articles/geofile-everything-in-the-radius-with-postgis/

此外,distanceWithin()函数以距离为单位将距离转换为地理距离,但是休眠Spatial不支持该距离,因此还有另一种方法可以根据需要以十进制距离提供距离。下面提到小数点。

用于十进制转换 LINK https://en.wikipedia.org/wiki/Decimal_degrees