I have a table with a column of type geography(Point,4326)
(using PostGIS).
I only need to use this column in the WHERE condition when querying the table. E.g. in the query below, geog
is the name of that column.
@Query(value = "SELECT pois.*\n" +
"FROM pois,\n" +
"(select ST_MakePoint(:lat,:lon)::geography as poi) as poi\n" +
"WHERE ST_DWithin(geog, poi, 400)\n" +
"ORDER BY ST_Distance(geog, poi)", nativeQuery = true)
public List<PointOfInterest> getPOIsAroundLocation(@Param("lat") double lat,
@Param("lon") double lon);
However, in the entity class PointOfInterest
, I don't know how to map that column, since I don't have a Java type equivalent to the geography(Point,4326)
database type.
If I don't mention the column at all in the class, it won't be created in the database (I have spring.jpa.hibernate.ddl-auto=create
), and the query will fail.
What can I do? Is there a way to create a column with a java type (maybe Object
?) and then map it to the db type with some annotation? Or is there a way to tell Spring Data about the db column without actually adding a field I won't use in the class?
Here is the PointOfInterest
class:
@Data
@Entity(name = "pois")
public abstract class PointOfInterest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private final double latitude;
private final double longitude;
private final PoiType poiType;
public PointOfInterest() {
this.latitude = this.longitude = 0;
poiType = null;
}
public PointOfInterest(double latitude, double longitude, PoiType poiType) {
this.latitude = latitude;
this.longitude = longitude;
this.poiType = poiType;
}
}
After I found out about hibernate-spatial from the comment of @Pilosa, I added some dependencies:
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.16.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>5.4.10.Final</version>
</dependency>
And I added a org.locationtech.jts.geom.Point
field in the Entity class to map the geography column.
@JsonIgnore
@Column(columnDefinition = "geography(Point,4326)")
private Point geog;
The @JsonIgnore
annotation is because jackson threw a stack overflow exception when trying to deserialize the field (see related question). This solution worked for me since I only use the point for querying, and I don't need its value.