在我的PostgreSQL 9.3 + PostGIS 2.1.5中,我有一个表PLACE,其列coordinates类型为Geometry(Point,26910)。
coordinates
Geometry(Point,26910)
我想将其映射到 使用Hibernate 4.0.0 +的PlaceSpring Boot 1.1.9 Web应用程序中的实体 。PlaceREST存储库中可用。
Hibernate 4.0.0 +
PlaceSpring Boot 1.1.9 Web
PlaceREST
不幸的是,当我GET http://localhost:8080/mywebapp/places收到 这个奇怪的JSON响应时:
http://localhost:8080/mywebapp/places
{ "_embedded" : { "venues" : [ { "id" : 1, "coordinates" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "envelope" : { "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" seems to be for older versions of 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> <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>
有点奇怪的配置,我在互联网上找到了,它是目前最有效的配置。
我希望有人可以帮助我解决这个问题。:)
最后,我发现我的配置是OK,可能是杰克逊是无法管理Point正确的数据类型。因此,我自定义了其JSON序列化和反序列化:
将这些注释添加到我们的coordinates字段中:
@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 [HTML_REMOVED] {
@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); }
}
创建这样的反序列化器:
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 {
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.