0

I have an query that returns an interface OverlayDTO that I get from a native query. center is PostGIS point and geometry as you might have guessed it is geometry

@Query("SELECT " +
        "o.geometry as geometry, " +
        "o.center as center, " +
        "FROM Overlay o " +
        "WHERE  o.layer.id = :layerId")
List<OverlayDTO> getAllOverlays(long layerId);

Interface:

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;

public interface OverlayDTO {
    Geometry getGeometry();
    Point getCenter();
}

I want to send it through REST API like this (if possible) (it should call a service and do some more logic, but this is the basic gist of it)

    @GetMapping(value="{layerId}")
public ResponseEntity<List<OverlayDTO>> getCompanyLayers(@PathVariable Long layerId) {
    List<OverlayDTO> overlays = mapRepository.getAllOverlays(layerId);
        
    return ResponseEntity.ok(overlays);
}

However, I get an error that Jackson was unable to map due to recursion.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]

How could I fix this issue? Should I query data differently, or should I build my own DTO class and just send a POJO? Or do I need to build some serializer/deserializer?

2 Answers 2

2

You need to register a Jackson Module that provides appropriate serializers and deserializers for JTS Geometry objects. A good candidate is jackson-datatype-jts.

If you want an example on how to do this, you could check out this blog post. (I wrote it using an alternative geometry library, but the approach should work with JTS and the jackson-datatype-jts module).

Sign up to request clarification or add additional context in comments.

1 Comment

The answer should work, however, I ended up using this jackson-datatype-jts implementation mvnrepository.com/artifact/org.n52.jackson/jackson-datatype-jts
0

There is a common exchange format, GeoJSON. You would likely have to code JTS to do this, or PostGIS has functions to generate GeoJSON directly from your DB objects.

Another somewhat simpler approach is to convert your objects to WKT and return them in a String. Both PostGIS, and JTS can generate and convert from WKT. This may or may not be easier for other services to consume depending on the system making the call. The only annoying thing about WKT, is the SRID is assumed. I've created my services to have a parameter to request the SRID the client would like (this of course requires that you can convert to the SRID requested), or, make your services always return data in a de facto standard, like 4326.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.