Map a PostGIS geometry point field with Hibernate on Spring Boot Map a PostGIS geometry point field with Hibernate on Spring Boot spring spring

Map a PostGIS geometry point field with Hibernate on Spring Boot


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.


The solutions above helped me to fix the problem. I simplify it so other people can understand.

I included this library in my pom.xml:

<dependency>  <groupId>com.bedatadriven</groupId>  <artifactId>jackson-datatype-jts</artifactId>  <version>2.2</version></dependency>

This is the POJO object I used. Then I was able to get the REST call to work without the envelope error and proper coordinates.

import com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer;import com.bedatadriven.jackson.datatype.jts.serialization.GeometrySerializer;import com.fasterxml.jackson.databind.annotation.JsonDeserialize;import com.fasterxml.jackson.databind.annotation.JsonSerialize;import com.vividsolutions.jts.geom.Geometry;@Entity@Table(name = "boundary")public class Boundary {    private int id;    private Geometry geometry;    @Id    public int getId() {        return ogc_fid;    }    public void setId(int id) {        this.id = id;    }        @JsonSerialize(using = GeometrySerializer.class)    @JsonDeserialize(using = GeometryDeserializer.class)    @Column(name = "geometry", columnDefinition = "Geometry")    public Geometry getGeometry() {        return geometry;    }    public void setGeometry(Geometry geometry) {        this.geometry = geometry;    }}

My table had these 2 columns:

id       | integer            geometry | geometry(Geometry,4326) |