postgresqlspring-bootjpahibernate-native-query

JSON operators syntax (::json) in JPA native query


I have a query works perfectly with postgresql

SELECT json_build_object('type', 'FeatureCollection', 'features', json_agg(ST_AsGeoJSON(geo.*)::json))
FROM (SELECT t.track_id, p.video_id, ST_MakeLine(p.location)
      FROM point as p inner join track as t on p.video_id = t.video_id
      group by p.video_id, t.track_id
      order by track_id) as geo;

But it doesn't work with JPA native query

@Query(value = "SELECT json_build_object('type', 'FeatureCollection', 'features', json_agg(ST_AsGeoJSON(g.*)::json)) " +
            "FROM (SELECT t.track_id, p.video_id, ST_MakeLine(p.location) " +
            "FROM point as p inner join track as t on p.video_id = t.video_id " +
            "group by p.video_id, t.track_id " +
            "order by track_id) as g",
            nativeQuery = true)

ERROR: syntax error at or near ":"

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessResourceUsageException: JDBC exception executing SQL [SELECT json_build_object('type', 'FeatureCollection', 'features', json_agg(ST_AsGeoJSON(g.*):json)) FROM (SELECT t.track_id, p.video_id, ST_MakeLine(p.location) FROM point as p inner join track as t on p.video_id = t.video_id group by p.video_id, t.track_id order by track_id) as g] [ERROR: syntax error at or near ":" Position: 93] [n/a]; SQL [n/a]] with root cause

Can anyone help please?


Solution

  • You should escape each of the : character using , so that :: becomes \\:\\:, then everything will work:

    @Query(value = "SELECT json_build_object('type', 'FeatureCollection', 'features', json_agg(ST_AsGeoJSON(g.*)\\:\\:json)) " +
                "FROM (SELECT t.track_id, p.video_id, ST_MakeLine(p.location) " +
                "FROM point as p inner join track as t on p.video_id = t.video_id " +
                "group by p.video_id, t.track_id " +
                "order by track_id) as g",
                nativeQuery = true)