在Spring Boot上使用Hibernate映射PostGIS几何点字段 [英] Map a PostGIS geometry point field with Hibernate on Spring Boot

查看:181
本文介绍了在Spring Boot上使用Hibernate映射PostGIS几何点字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的PostgreSQL 9.3 + PostGIS 2.1.5中,我有一个表 PLACE ,其中一列坐标 code> Geometry(Point,26910)。



我想将它映射到 Place 实体在我的Spring Boot 1.1.9 Web应用程序中,它使用Hibernate 4.0.0 +。 Place 可用于REST存储库。



不幸的是,当我 GET http:// localhost:8080 / mywebapp / places 我收到了这个奇怪的JSON响应

  {

_embedded:{

场地:[{

id:1,

坐标:{

信封:{

信封:{

信封:{

信封:{

信封:{

信封:{

信封:{

envelope:{

envelope:{

envelope:{

envelope:{

信封:{

信封:{

e信封:{

信封:{

信封:{

信封:{

envelope:{

envelope:{

等等无限地...! Spring的日志并没有帮助..



我正在处理这个application.properties:

  spring.jpa.database-platform = org.hibernate.spatial.dialect.postgis.PostgisDialect 
spring.jpa.show-sql = false
spring.jpa.hibernate.ddl -auto = update

spring.datasource.url = jdbc:postgresql://192.168.1.123/mywebapp
spring.datasource.username = postgres
spring.datasource.password = mypwd
spring.datasource.driverClassName = org.postgresql.Driver

首先,是可以使用 database-platform 而不是 database
也许我不得不使用下面的设置而不是上面的设置?

  spring.datasource.url = jdbc: postgresql_postGIS://192.168.1.123/mywebapp 
spring.datasource.driverClassName = org.postgis.DriverWrapper

无论如何,我的实体是这样的:

  @Entity 
public class Place {
@ Id
public int id;
@Column(columnDefinition =Geometry)
@Type(type =org.hibernate.spatial.GeometryType)//\"org.hibernatespatial.GeometryUserType似乎适用于旧版本的Hibernate Spatial
public com.vividsolutions.jts.geom.Point coordinates;
}

我的pom.xml包含以下相关部分:

 < dependency> 
< groupId> org.postgresql< / groupId>
< artifactId> postgresql< / artifactId>
< version> 9.3-1102-jdbc41< / version>
< /依赖关系>
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-spatial< / artifactId>
< version> 4.3< / version><! - 与Hibernate 4.3.x兼容 - >
<排除项>
<排除>
< artifactId> postgresql< / artifactId>
< groupId> postgresql< / groupId>
< /排除>
< /排除>
< /依赖关系>

有点奇怪的配置,我在互联网上发现它,它是现在最适合的配置。



我希望有人能够帮助我这个神秘莫测。 :)

解决方案

最后我发现我的配置没问题,可能是 Jackson code> Point 数据类型正确。所以我定制了它的JSON序列化和反序列化:




  • 将这些注释添加到我们的坐标中
    $ p $ @JsonSerialize(using = PointToJsonSerializer.class)
    @JsonDeserialize(using = JsonToPointDeserializer.class )


  • 创建这样的序列化程序:

      import java.io.IOException; 
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.JsonSerializer;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.vividsolutions.jts.geom.Point;

    公共类PointToJsonSerializer扩展了JsonSerializer< Point> {
    $ b @Override
    public void serialize(Point value,JsonGenerator jgen,
    SerializerProvider provider)throws IOException,
    JsonProcessingException {

    String jsonValue =null;
    尝试
    {
    if(value!= null){
    double lat = value.getY();
    double lon = value.getX();
    jsonValue = String.format(POINT(%s%s),lat,lon);
    }
    }
    catch(Exception e){}

    jgen.writeString(jsonValue);
    }

    }


  • 创建这样的反序列化器:

      import java.io.IOException; 
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.vividsolutions.jts.geom.Coordinate;
    import com.vividsolutions.jts.geom.GeometryFactory;
    import com.vividsolutions.jts.geom.Point;
    import com.vividsolutions.jts.geom.PrecisionModel;

    public class JsonToPointDeserializer扩展了JsonDeserializer< Point> {

    private final static GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(),26910);
    $ b $ @Override
    public Point反序列化(JsonParser jp,DeserializationContext ctxt)
    抛出IOException,JsonProcessingException {

    try {
    String text = jp.getText();
    if(text == null || text.length()<= 0)
    return null;

    String [] coordinates = text.replaceFirst(POINT?\\(,).replaceFirst(\\)).split() ;
    double lat = Double.parseDouble(coordinates [0]);
    double lon = Double.parseDouble(coordinates [1]);

    Point point = geometryFactory.createPoint(new Coordinate(lat,lon));
    回报点;
    }
    catch(Exception e){
    return null;
    }
    }

    }




也许你也可以使用此序列化程序这个反序列化器,可用在这里


In my PostgreSQL 9.3 + PostGIS 2.1.5 I have a table PLACE with a column coordinates of type Geometry(Point,26910).

I want to map it to Place entity in my Spring Boot 1.1.9 web application, which uses Hibernate 4.0.0 + . Place is available with a REST repository.

Unfortunately when I GET http://localhost:8080/mywebapp/places I receive this strange JSON response:

{

  "_embedded" : {

    "venues" : [ {

      "id" : 1,

      "coordinates" : {

        "envelope" : {

          "envelope" : {

            "envelope" : {

              "envelope" : {

                "envelope" : {

                  "envelope" : {

                    "envelope" : {

                      "envelope" : {

                        "envelope" : {

                          "envelope" : {

                            "envelope" : {

                              "envelope" : {

                                "envelope" : {

                                  "envelope" : {

                                    "envelope" : {

                                      "envelope" : {

                                        "envelope" : {

                                          "envelope" : {

                                            "envelope" : {

and so on indefinetely...! Spring log doesn't help..

I'm working with this application.properties:

spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update

spring.datasource.url=jdbc:postgresql://192.168.1.123/mywebapp
spring.datasource.username=postgres
spring.datasource.password=mypwd
spring.datasource.driverClassName=org.postgresql.Driver

First of all, is it ok to use database-platform instead of database? And maybe do I have to use following settings instead of the above?

spring.datasource.url=jdbc:postgresql_postGIS://192.168.1.123/mywebapp
spring.datasource.driverClassName=org.postgis.DriverWrapper

Anyway my entity is something like this:

@Entity
public class Place {
    @Id
    public int id;
    @Column(columnDefinition="Geometry")
    @Type(type="org.hibernate.spatial.GeometryType")    //"org.hibernatespatial.GeometryUserType" seems to be for older versions of Hibernate Spatial
    public com.vividsolutions.jts.geom.Point coordinates;
}

My pom.xml contains this relevant part:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-spatial</artifactId>
    <version>4.3</version><!-- compatible with Hibernate 4.3.x -->
    <exclusions>
        <exclusion>
            <artifactId>postgresql</artifactId>
            <groupId>postgresql</groupId>
        </exclusion>
    </exclusions>
</dependency>

A bit strange configuration, I found it on the internet, it is the one that works best for now.

I hope that someone could help me with this mistery. :)

解决方案

Finally I discovered that my configuration is ok and might be Jackson that cannot manage Point data type correctly. So I customized its JSON serialization and deserialization:

  • add these annotations to our coordinates field:

    @JsonSerialize(using = PointToJsonSerializer.class)
    @JsonDeserialize(using = JsonToPointDeserializer.class)
    

  • create such serializer:

    import java.io.IOException;
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.JsonSerializer;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.vividsolutions.jts.geom.Point;
    
    public class PointToJsonSerializer extends JsonSerializer<Point> {
    
        @Override
        public void serialize(Point value, JsonGenerator jgen,
                SerializerProvider provider) throws IOException,
                JsonProcessingException {
    
            String jsonValue = "null";
            try
            {
                if(value != null) {             
                    double lat = value.getY();
                    double lon = value.getX();
                    jsonValue = String.format("POINT (%s %s)", lat, lon);
                }
            }
            catch(Exception e) {}
    
            jgen.writeString(jsonValue);
        }
    
    }
    

  • create such deserializer:

    import java.io.IOException;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.vividsolutions.jts.geom.Coordinate;
    import com.vividsolutions.jts.geom.GeometryFactory;
    import com.vividsolutions.jts.geom.Point;
    import com.vividsolutions.jts.geom.PrecisionModel;
    
    public class JsonToPointDeserializer extends JsonDeserializer<Point> {
    
        private final static GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 26910); 
    
        @Override
        public Point deserialize(JsonParser jp, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
    
            try {
                String text = jp.getText();
                if(text == null || text.length() <= 0)
                    return null;
    
                String[] coordinates = text.replaceFirst("POINT ?\\(", "").replaceFirst("\\)", "").split(" ");
                double lat = Double.parseDouble(coordinates[0]);
                double lon = Double.parseDouble(coordinates[1]);
    
                Point point = geometryFactory.createPoint(new Coordinate(lat, lon));
                return point;
            }
            catch(Exception e){
                return null;
            }
        }
    
    }
    

Maybe you can also use this serializer and this deserializer, available here.

这篇关于在Spring Boot上使用Hibernate映射PostGIS几何点字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆