Hibernate Spatial 5 - 几何类型

Hibernate Spatial 5 - GeometryType

将 Hibernate-spatial 升级到版本 5.0.0.CR2 后,以下声明不再有效:

@Column(columnDefinition = "geometry(Point,4326)")
@Type(type = "org.hibernate.spatial.GeometryType")
private Point position;

有一个:

org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [org.hibernate.spatial.GeometryType]

如我所见,class 不再存在于 Jar 文件中。 GeometryType 发生了什么变化,它是如何被替换的?或者是否有另一个 jar 文件要包含?

编辑:澄清一下。我将 Hibernate-Spatial 与 PostgreSQL-Postgis 数据库结合使用。

好吧,解决方案太容易看出来了。只需删除 @Type 注解,声明如下所示:

@Column(columnDefinition = "geometry(Point,4326)")
private Point position;

Source:

Note the @Type annotation. This informs Hibernate that the location attribute is of type Geometry. The @Type annotation is Hibernate specific, and the only non-JPA annotation that is required. (In future versions of Hibernate (version 5 and later) it will no longer be necessary to explicitly declare the Type of Geometry-valued attributes.)

上面 Denis 建议的解决方案在 Hiberate 5 spatial 和 Mysql 上对我不起作用。但是以下注释对我有用

  @Column(name = "location",columnDefinition="Geometry")
  private Geometry location;


  @Column(name = "pointlocation",columnDefinition="Point")
  private Point pointlocation;

如果您是 运行 Hibernate 5.3+,您可以跳过列定义

  @Column(name = "location")
  private Geometry location;


  @Column(name = "pointlocation")
  private Point pointlocation;

我正在使用 hibernate 4.3.6 和 hibernate spatial 5.2.2。上面建议的解决方案对我不起作用。 但是下面的代码有效如果我添加休眠空间 4.3

@Type(type="org.hibernate.spatial.GeometryType")
private Point location;

所以我已经和这个问题斗争了几天,问题是我希望数据库类型来自 postgis 类型,以便我 运行 最近邻居的有效距离查询等.我终于弄明白了怎么做,并想与社区分享,所以我创建了一个包含问题解决方案的演示项目。

我的设置是一个带有 Postgis 的 PostgreSQL 数据库,Spring boot jpa,Hibernate 5+,Hibernate-spatial 5+ 并且还添加了转换为 rest 输出,这再次需要来自 jackson 的特殊模块。

项目位于 https://github.com/Wisienkas/springJpaGeo

您要求的重要代码是:

@type(type = "jts_geometry")
private Point point;

对于 Hibernate Spatial 5.2.x,您只需要实体中的以下内容即可。

private Point location;

您不需要像上面提到的解决方案那样的 columnDefinition 或 Type。

一些额外的细节和检查以查看以上是否有效

  • 一旦您 运行 在 mysql 中设置并使用 desc table_name,您应该会看到 geometry 的字段类型。这表明您的休眠到数据库映射工作正常。
  • 现在尝试从 java 创建实体和 repo.save(entity),您的实体应该可以正常保存,不会出现任何错误。

如果上述设置效果不佳,您通常会收到错误

Data truncation: Cannot get geometry object from data you send to the GEOMETRY field Blockquote

希望能帮助别人节省我浪费的 6 个小时!

显然你的 Hibernate 库也需要相同的版本。

我使用的是 postgis / springboot / hibernate-spatial。

最初 Hibernate-Spatial 是 @ 5.4.10.Final,即使使用此处的解决方案也无法正常工作。

然后我查看了我的 Maven 依赖项中的 hibernate 版本 (hibernate-commons-annotations-5.1.0.Final.jar),并记得在某个地方看到 hibernate 的版本需要匹配。

所以我将我的 Hibernate-Spatial 降级到 5.1 并且以下映射语句在没有任何更多信息的情况下工作:

// Geometry Object is from the following import
import com.vividsolutions.jts.geom.*;

@Column(name="domain_loc")
private Geometry location;

对我来说,数据按预期存储在 PostgreSQL 中,但使用 REST API 检索数据失败并出现反序列化错误。 这就是我使用 PostgreSQL 12 和 Spring Boot 的方法。

已将其包含在 application.properties 文件中

spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect

pom.xml 变化

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.20.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-spatial</artifactId>
    <version>5.4.20.Final</version>
</dependency>
<dependency>
    <groupId>org.n52.jackson</groupId>
    <artifactId>jackson-datatype-jts</artifactId>
    <version>1.2.9</version>
</dependency>

使用@Configuration annnotation创建下面的Bean

import org.n52.jackson.datatype.jts.JtsModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfig {

    @Bean
    public JtsModule jtsModule() {
        return new JtsModule();
    }

}

并在您的@Entity class 中,确保

import org.n52.jackson.datatype.jts.GeometryDeserializer;
import org.n52.jackson.datatype.jts.GeometrySerializer;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.locationtech.jts.geom.Point;
    
@Column(name="the_geom", columnDefinition = "POINT")
@JsonSerialize(using = GeometrySerializer.class)
@JsonDeserialize(contentUsing = GeometryDeserializer.class)
private Point point;

经过这些更改后,我的 Rest API returns 数据采用预期格式

"point": {
            "type": "Point",
            "coordinates": [
                53.85151,
                -1.55973
            ]
        }