在Spring Boot上使用Hibernate映射PostGIS几何点字段 [英] Map a PostGIS geometry point field with Hibernate on Spring Boot
问题描述
在我的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序列化和反序列化:
-
将这些注释添加到我们的
坐标中$ c
$ 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屋!