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

Ant*_*ton 16 java postgresql hibernate 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;
Run Code Online (Sandbox Code Playgroud)

persistence.xml中的方言:

<property name="hibernate.dialect"  value="org.hibernate.spatial.dialect.postgis.PostgisDialect" />
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

所以它似乎试图将值保持为PostGIS的几何类型.但我想用简单的Point.

Pia*_*nov 6

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

示例如下:

用于创建具有LAT和LONG的一些表的SQL查询:

CREATE TABLE some_table (
  lat    NUMBER(..., ...),
  long   NUMBER(..., ...),
...
);
Run Code Online (Sandbox Code Playgroud)

可嵌入点实体:

@Embeddable
public class Point {
    private BigDecimal x;
    private BigDecimal y;
 ...
}
Run Code Online (Sandbox Code Playgroud)

您的自定义实体:

@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;
...
}
Run Code Online (Sandbox Code Playgroud)


And*_*lfe 6

在您的数据库中安装POSTGIS EXTENSIONS.

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

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

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

<property name="hibernate.dialect"  value="org.hibernate.spatial.dialect.postgis.PostgisDialect" />
Run Code Online (Sandbox Code Playgroud)

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

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

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

@bluish有帮助吗?

  • 虽然你给出了一个很好的答案,但OP要求一个没有PostGIS的解决方案。 (2认同)

小智 5

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


Hil*_*lle 5

由于我不完全确定这个问题,让我先尝试一下解释:

要映射其类型的字段的实体com.vividsolutions.jts.geom.Point到类型的PostgreSQL数据库列"点"(参见PostgreSQL的几何类型)中使用Hibernate,限制自己的"标准"(即休眠提供方言PostgreSQLDialect.

一些研究使我得出结论,上面提到的hibernate支持的标准方言根本不支持PostgreSQL点类型.因此,您可能希望提供自己的UserType.从hibernate手册中查看Custom类型,或者从博客中了解和编写Hibernate自定义用户类型.